blob: 628992537e5385ebcf8a3498c46daf428a9782e7 [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
Jon Hallf539eb92017-05-22 17:18:42 -07002209 def checkIntentState( self, intentsId, 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:
kelvin-onlabf512e942015-06-08 19:42:59 -07002216 expectedState - Check the expected state(s) of each intents
2217 state in the list.
2218 *NOTE: You can pass in a list of expected state,
2219 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002220 Return:
Jon Hall53158082017-05-18 11:17:00 -07002221 Returns main.TRUE only if all intent are the same as expected states,
2222 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002223 """
2224 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002225 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002226 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002227 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002228 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002229 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002230 "getting intents state" )
2231 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002232
2233 if isinstance( expectedState, types.StringType ):
2234 for intents in intentsDict:
2235 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002236 main.log.debug( self.name + " : Intent ID - " +
2237 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002238 " actual state = " +
2239 intents.get( 'state' )
2240 + " does not equal expected state = "
2241 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002242 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002243
2244 elif isinstance( expectedState, types.ListType ):
2245 for intents in intentsDict:
2246 if not any( state == intents.get( 'state' ) for state in
2247 expectedState ):
2248 main.log.debug( self.name + " : Intent ID - " +
2249 intents.get( 'id' ) +
2250 " actual state = " +
2251 intents.get( 'state' ) +
2252 " does not equal expected states = "
2253 + str( expectedState ) )
2254 returnValue = main.FALSE
2255
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002256 if returnValue == main.TRUE:
2257 main.log.info( self.name + ": All " +
2258 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002259 " intents are in " + str( expectedState ) +
2260 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002261 return returnValue
2262 except TypeError:
2263 main.log.exception( self.name + ": Object not as expected" )
2264 return None
2265 except pexpect.EOF:
2266 main.log.error( self.name + ": EOF exception found" )
2267 main.log.error( self.name + ": " + self.handle.before )
2268 main.cleanup()
2269 main.exit()
2270 except Exception:
2271 main.log.exception( self.name + ": Uncaught exception!" )
2272 main.cleanup()
2273 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002274
Jon Hallf539eb92017-05-22 17:18:42 -07002275 def compareBandwidthAllocations( self, expectedAllocations ):
2276 """
2277 Description:
2278 Compare the allocated bandwidth with the given allocations
2279 Required:
2280 expectedAllocations - The expected ONOS output of the allocations command
2281 Return:
2282 Returns main.TRUE only if all intent are the same as expected states,
2283 otherwise returns main.FALSE.
2284 """
2285 # FIXME: Convert these string comparisons to object comparisons
2286 try:
2287 returnValue = main.TRUE
2288 bandwidthFailed = False
2289 rawAlloc = self.allocations()
2290 expectedFormat = StringIO( expectedAllocations )
2291 ONOSOutput = StringIO( rawAlloc )
2292 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2293 str( expectedFormat ) ) )
2294
2295 for actual, expected in izip( ONOSOutput, expectedFormat ):
2296 actual = actual.rstrip()
2297 expected = expected.rstrip()
2298 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2299 if actual != expected and 'allocated' in actual and 'allocated' in expected:
2300 marker1 = actual.find('allocated')
2301 m1 = actual[:marker1]
2302 marker2 = expected.find('allocated')
2303 m2 = expected[:marker2]
2304 if m1 != m2:
2305 bandwidthFailed = True
2306 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2307 bandwidthFailed = True
2308 expectedFormat.close()
2309 ONOSOutput.close()
2310
2311 if bandwidthFailed:
2312 main.log.error("Bandwidth not allocated correctly using Intents!!")
2313 returnValue = main.FALSE
2314 return returnValue
2315 except TypeError:
2316 main.log.exception( self.name + ": Object not as expected" )
2317 return None
2318 except pexpect.EOF:
2319 main.log.error( self.name + ": EOF exception found" )
2320 main.log.error( self.name + ": " + self.handle.before )
2321 main.cleanup()
2322 main.exit()
2323 except Exception:
2324 main.log.exception( self.name + ": Uncaught exception!" )
2325 main.cleanup()
2326 main.exit()
2327
You Wang66518af2016-05-16 15:32:59 -07002328 def compareIntent( self, intentDict ):
2329 """
2330 Description:
2331 Compare the intent ids and states provided in the argument with all intents in ONOS
2332 Return:
2333 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2334 Arguments:
2335 intentDict: a dictionary which maps intent ids to intent states
2336 """
2337 try:
2338 intentsRaw = self.intents()
2339 intentsJson = json.loads( intentsRaw )
2340 intentDictONOS = {}
2341 for intent in intentsJson:
2342 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002343 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002344 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002345 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002346 str( len( intentDict ) ) + " expected and " +
2347 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002348 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002349 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002350 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002351 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2352 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002353 else:
2354 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2355 main.log.debug( self.name + ": intent ID - " + intentID +
2356 " expected state is " + intentDict[ intentID ] +
2357 " but actual state is " + intentDictONOS[ intentID ] )
2358 returnValue = main.FALSE
2359 intentDictONOS.pop( intentID )
2360 if len( intentDictONOS ) > 0:
2361 returnValue = main.FALSE
2362 for intentID in intentDictONOS.keys():
2363 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002364 if returnValue == main.TRUE:
2365 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2366 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002367 except KeyError:
2368 main.log.exception( self.name + ": KeyError exception found" )
2369 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002370 except ( TypeError, ValueError ):
2371 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002372 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002373 except pexpect.EOF:
2374 main.log.error( self.name + ": EOF exception found" )
2375 main.log.error( self.name + ": " + self.handle.before )
2376 main.cleanup()
2377 main.exit()
2378 except Exception:
2379 main.log.exception( self.name + ": Uncaught exception!" )
2380 main.cleanup()
2381 main.exit()
2382
YPZhang14a4aa92016-07-15 13:37:15 -07002383 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002384 """
2385 Description:
2386 Check the number of installed intents.
2387 Optional:
2388 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002389 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002390 Return:
2391 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2392 , otherwise, returns main.FALSE.
2393 """
2394
2395 try:
2396 cmd = "intents -s -j"
2397
2398 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002399 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002400 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002401 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002402 response = json.loads( response )
2403
2404 # get total and installed number, see if they are match
2405 allState = response.get( 'all' )
2406 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002407 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002408 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002409 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002410 return main.FALSE
2411
Jon Hallc6793552016-01-19 14:18:37 -08002412 except ( TypeError, ValueError ):
2413 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002414 return None
2415 except pexpect.EOF:
2416 main.log.error( self.name + ": EOF exception found" )
2417 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002418 if noExit:
2419 return main.FALSE
2420 else:
2421 main.cleanup()
2422 main.exit()
Jon Halle0f0b342017-04-18 11:43:47 -07002423 except pexpect.TIMEOUT:
2424 main.log.error( self.name + ": ONOS timeout" )
2425 return None
GlennRCed771242016-01-13 17:02:47 -08002426 except Exception:
2427 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002428 if noExit:
2429 return main.FALSE
2430 else:
2431 main.cleanup()
2432 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002433
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002434 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002435 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002436 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002437 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002438 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002439 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002440 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002441 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002442 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002443 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002444 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002445 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002446 if noCore:
2447 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002448 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002449 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002450 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002451 assert "Command not found:" not in handle, handle
2452 if re.search( "Error:", handle ):
2453 main.log.error( self.name + ": flows() response: " +
2454 str( handle ) )
2455 return handle
2456 except AssertionError:
2457 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002458 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002459 except TypeError:
2460 main.log.exception( self.name + ": Object not as expected" )
2461 return None
Jon Hallc6793552016-01-19 14:18:37 -08002462 except pexpect.TIMEOUT:
2463 main.log.error( self.name + ": ONOS timeout" )
2464 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002465 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002466 main.log.error( self.name + ": EOF exception found" )
2467 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002468 main.cleanup()
2469 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002470 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002471 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002472 main.cleanup()
2473 main.exit()
2474
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002475 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002476 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002477 count = int( count ) if count else 0
2478 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002479
Jon Halle0f0b342017-04-18 11:43:47 -07002480 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002481 """
2482 Description:
GlennRCed771242016-01-13 17:02:47 -08002483 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002484 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2485 if the count of those states is 0, which means all current flows
2486 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002487 Optional:
GlennRCed771242016-01-13 17:02:47 -08002488 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002489 Return:
2490 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002491 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002492 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002493 """
2494 try:
GlennRCed771242016-01-13 17:02:47 -08002495 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2496 checkedStates = []
2497 statesCount = [0, 0, 0, 0]
2498 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002499 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002500 if rawFlows:
2501 # if we didn't get flows or flows function return None, we should return
2502 # main.Flase
2503 checkedStates.append( json.loads( rawFlows ) )
2504 else:
2505 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002506 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002507 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002508 try:
2509 statesCount[i] += int( c.get( "flowCount" ) )
2510 except TypeError:
2511 main.log.exception( "Json object not as expected" )
2512 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002513
GlennRCed771242016-01-13 17:02:47 -08002514 # We want to count PENDING_ADD if isPENDING is true
2515 if isPENDING:
2516 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2517 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002518 else:
GlennRCed771242016-01-13 17:02:47 -08002519 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2520 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002521 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002522 except ( TypeError, ValueError ):
2523 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002524 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002525
YPZhang240842b2016-05-17 12:00:50 -07002526 except AssertionError:
2527 main.log.exception( "" )
2528 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002529 except pexpect.TIMEOUT:
2530 main.log.error( self.name + ": ONOS timeout" )
2531 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002532 except pexpect.EOF:
2533 main.log.error( self.name + ": EOF exception found" )
2534 main.log.error( self.name + ": " + self.handle.before )
2535 main.cleanup()
2536 main.exit()
2537 except Exception:
2538 main.log.exception( self.name + ": Uncaught exception!" )
2539 main.cleanup()
2540 main.exit()
2541
GlennRCed771242016-01-13 17:02:47 -08002542 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002543 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002544 """
andrewonlab87852b02014-11-19 18:44:19 -05002545 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002546 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002547 a specific point-to-point intent definition
2548 Required:
GlennRCed771242016-01-13 17:02:47 -08002549 * ingress: specify source dpid
2550 * egress: specify destination dpid
2551 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002552 Optional:
GlennRCed771242016-01-13 17:02:47 -08002553 * offset: the keyOffset is where the next batch of intents
2554 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002555 * noExit: If set to True, TestON will not exit if any error when issus command
2556 * getResponse: If set to True, function will return ONOS response.
2557
GlennRCed771242016-01-13 17:02:47 -08002558 Returns: If failed to push test intents, it will returen None,
2559 if successful, return true.
2560 Timeout expection will return None,
2561 TypeError will return false
2562 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002563 """
andrewonlab87852b02014-11-19 18:44:19 -05002564 try:
GlennRCed771242016-01-13 17:02:47 -08002565 if background:
2566 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002567 else:
GlennRCed771242016-01-13 17:02:47 -08002568 back = ""
2569 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002570 ingress,
2571 egress,
2572 batchSize,
2573 offset,
2574 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002575 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002576 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002577 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002578 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002579 if getResponse:
2580 return response
2581
GlennRCed771242016-01-13 17:02:47 -08002582 # TODO: We should handle if there is failure in installation
2583 return main.TRUE
2584
Jon Hallc6793552016-01-19 14:18:37 -08002585 except AssertionError:
2586 main.log.exception( "" )
2587 return None
GlennRCed771242016-01-13 17:02:47 -08002588 except pexpect.TIMEOUT:
2589 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002590 return None
andrewonlab87852b02014-11-19 18:44:19 -05002591 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002592 main.log.error( self.name + ": EOF exception found" )
2593 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002594 main.cleanup()
2595 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002596 except TypeError:
2597 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002598 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002599 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002600 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002601 main.cleanup()
2602 main.exit()
2603
YPZhangebf9eb52016-05-12 15:20:24 -07002604 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002605 """
2606 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002607 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002608 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002609 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002610 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002611 """
YPZhange3109a72016-02-02 11:25:37 -08002612
YPZhangb5d3f832016-01-23 22:54:26 -08002613 try:
YPZhange3109a72016-02-02 11:25:37 -08002614 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002615 cmd = "flows -c added"
2616 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2617 if rawFlows:
2618 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002619 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002620 for l in rawFlows:
2621 totalFlows += int(l.split("Count=")[1])
2622 else:
2623 main.log.error("Response not as expected!")
2624 return None
2625 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002626
You Wangd3cb2ce2016-05-16 14:01:24 -07002627 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002628 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002629 return None
2630 except pexpect.EOF:
2631 main.log.error( self.name + ": EOF exception found" )
2632 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002633 if not noExit:
2634 main.cleanup()
2635 main.exit()
2636 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002637 except pexpect.TIMEOUT:
2638 main.log.error( self.name + ": ONOS timeout" )
2639 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002640 except Exception:
2641 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002642 if not noExit:
2643 main.cleanup()
2644 main.exit()
2645 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002646
YPZhang14a4aa92016-07-15 13:37:15 -07002647 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002648 """
2649 Description:
2650 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002651 Optional:
2652 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002653 Return:
2654 The number of intents
2655 """
2656 try:
2657 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002658 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002659 if response is None:
2660 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002661 response = json.loads( response )
2662 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002663 except ( TypeError, ValueError ):
2664 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002665 return None
2666 except pexpect.EOF:
2667 main.log.error( self.name + ": EOF exception found" )
2668 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002669 if noExit:
2670 return -1
2671 else:
2672 main.cleanup()
2673 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002674 except Exception:
2675 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002676 if noExit:
2677 return -1
2678 else:
2679 main.cleanup()
2680 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002681
kelvin-onlabd3b64892015-01-20 13:26:24 -08002682 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002683 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002684 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002685 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002686 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002687 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002688 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002689 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002690 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002691 cmdStr += " -j"
2692 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002693 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002694 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002695 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002696 except AssertionError:
2697 main.log.exception( "" )
2698 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002699 except TypeError:
2700 main.log.exception( self.name + ": Object not as expected" )
2701 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002702 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002703 main.log.error( self.name + ": EOF exception found" )
2704 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002705 main.cleanup()
2706 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002707 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002708 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002709 main.cleanup()
2710 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002711
kelvin-onlabd3b64892015-01-20 13:26:24 -08002712 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002713 """
2714 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002715 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002716 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002717 """
andrewonlab867212a2014-10-22 20:13:38 -04002718 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002719 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002720 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002721 cmdStr += " -j"
2722 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002723 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002724 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002725 if handle:
2726 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002727 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002728 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002729 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002730 else:
2731 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002732 except AssertionError:
2733 main.log.exception( "" )
2734 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002735 except TypeError:
2736 main.log.exception( self.name + ": Object not as expected" )
2737 return None
andrewonlab867212a2014-10-22 20:13:38 -04002738 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002739 main.log.error( self.name + ": EOF exception found" )
2740 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002741 main.cleanup()
2742 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002743 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002744 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002745 main.cleanup()
2746 main.exit()
2747
kelvin8ec71442015-01-15 16:57:00 -08002748 # Wrapper functions ****************
2749 # Wrapper functions use existing driver
2750 # functions and extends their use case.
2751 # For example, we may use the output of
2752 # a normal driver function, and parse it
2753 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002754
kelvin-onlabd3b64892015-01-20 13:26:24 -08002755 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002756 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002757 Description:
2758 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002759 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002760 try:
kelvin8ec71442015-01-15 16:57:00 -08002761 # Obtain output of intents function
Jon Hall6021e062017-01-30 11:10:06 -08002762 intentsStr = self.intents(jsonFormat=True)
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002763 if intentsStr is None:
2764 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002765 # Convert to a dictionary
2766 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002767 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002768 for intent in intents:
2769 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002770 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002771 except TypeError:
2772 main.log.exception( self.name + ": Object not as expected" )
2773 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002774 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002775 main.log.error( self.name + ": EOF exception found" )
2776 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002777 main.cleanup()
2778 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002779 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002780 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002781 main.cleanup()
2782 main.exit()
2783
You Wang3c276252016-09-21 15:21:36 -07002784 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002785 """
2786 Determine the number of flow rules for the given device id that are
2787 in the added state
You Wang3c276252016-09-21 15:21:36 -07002788 Params:
2789 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002790 """
2791 try:
You Wang3c276252016-09-21 15:21:36 -07002792 if core:
2793 cmdStr = "flows any " + str( deviceId ) + " | " +\
2794 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2795 else:
2796 cmdStr = "flows any " + str( deviceId ) + " | " +\
2797 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002798 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002799 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002800 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002801 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002802 except AssertionError:
2803 main.log.exception( "" )
2804 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002805 except pexpect.EOF:
2806 main.log.error( self.name + ": EOF exception found" )
2807 main.log.error( self.name + ": " + self.handle.before )
2808 main.cleanup()
2809 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002810 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002811 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002812 main.cleanup()
2813 main.exit()
2814
kelvin-onlabd3b64892015-01-20 13:26:24 -08002815 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002816 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002817 Use 'devices' function to obtain list of all devices
2818 and parse the result to obtain a list of all device
2819 id's. Returns this list. Returns empty list if no
2820 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002821 List is ordered sequentially
2822
andrewonlab3e15ead2014-10-15 14:21:34 -04002823 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002824 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002825 the ids. By obtaining the list of device ids on the fly,
2826 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002827 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002828 try:
kelvin8ec71442015-01-15 16:57:00 -08002829 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002830 devicesStr = self.devices( jsonFormat=False )
2831 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002832
kelvin-onlabd3b64892015-01-20 13:26:24 -08002833 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002834 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002835 return idList
kelvin8ec71442015-01-15 16:57:00 -08002836
2837 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002838 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002839 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002840 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002841 # Split list further into arguments before and after string
2842 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002843 # append to idList
2844 for arg in tempList:
2845 idList.append( arg.split( "id=" )[ 1 ] )
2846 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002847
Jon Halld4d4b372015-01-28 16:02:41 -08002848 except TypeError:
2849 main.log.exception( self.name + ": Object not as expected" )
2850 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002851 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002852 main.log.error( self.name + ": EOF exception found" )
2853 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002854 main.cleanup()
2855 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002856 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002857 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002858 main.cleanup()
2859 main.exit()
2860
kelvin-onlabd3b64892015-01-20 13:26:24 -08002861 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002862 """
andrewonlab7c211572014-10-15 16:45:20 -04002863 Uses 'nodes' function to obtain list of all nodes
2864 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002865 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002866 Returns:
2867 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002868 """
andrewonlab7c211572014-10-15 16:45:20 -04002869 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002870 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002871 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002872 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002873 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002874 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002875 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002876 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002877 nodesJson = json.loads( nodesStr )
2878 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002879 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002880 except ( TypeError, ValueError ):
2881 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002882 return None
andrewonlab7c211572014-10-15 16:45:20 -04002883 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002884 main.log.error( self.name + ": EOF exception found" )
2885 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002886 main.cleanup()
2887 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002888 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002889 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002890 main.cleanup()
2891 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002892
kelvin-onlabd3b64892015-01-20 13:26:24 -08002893 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002894 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002895 Return the first device from the devices api whose 'id' contains 'dpid'
2896 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002897 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002898 try:
kelvin8ec71442015-01-15 16:57:00 -08002899 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002900 return None
2901 else:
kelvin8ec71442015-01-15 16:57:00 -08002902 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002903 rawDevices = self.devices()
2904 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002905 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002906 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002907 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2908 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002909 return device
2910 return None
Jon Hallc6793552016-01-19 14:18:37 -08002911 except ( TypeError, ValueError ):
2912 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002913 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002914 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002915 main.log.error( self.name + ": EOF exception found" )
2916 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002917 main.cleanup()
2918 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002919 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002920 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002921 main.cleanup()
2922 main.exit()
2923
You Wang24139872016-05-03 11:48:47 -07002924 def getTopology( self, topologyOutput ):
2925 """
2926 Definition:
2927 Loads a json topology output
2928 Return:
2929 topology = current ONOS topology
2930 """
2931 import json
2932 try:
2933 # either onos:topology or 'topology' will work in CLI
2934 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002935 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002936 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002937 except ( TypeError, ValueError ):
2938 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2939 return None
You Wang24139872016-05-03 11:48:47 -07002940 except pexpect.EOF:
2941 main.log.error( self.name + ": EOF exception found" )
2942 main.log.error( self.name + ": " + self.handle.before )
2943 main.cleanup()
2944 main.exit()
2945 except Exception:
2946 main.log.exception( self.name + ": Uncaught exception!" )
2947 main.cleanup()
2948 main.exit()
2949
Flavio Castro82ee2f62016-06-07 15:04:12 -07002950 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002951 """
Jon Hallefbd9792015-03-05 16:11:36 -08002952 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002953 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002954 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002955
Flavio Castro82ee2f62016-06-07 15:04:12 -07002956 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002957 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002958 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002959 logLevel = level to log to.
2960 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002961
Jon Hallefbd9792015-03-05 16:11:36 -08002962 Returns: main.TRUE if the number of switches and links are correct,
2963 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002964 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002965 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002966 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002967 try:
You Wang13310252016-07-31 10:56:14 -07002968 summary = self.summary()
2969 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002970 except ( TypeError, ValueError ):
2971 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2972 return main.ERROR
2973 try:
2974 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07002975 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002976 return main.ERROR
2977 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002978 # Is the number of switches is what we expected
2979 devices = topology.get( 'devices', False )
2980 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002981 nodes = summary.get( 'nodes', False )
2982 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002983 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002984 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002985 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002986 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002987 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2988 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002989 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002990 output = output + "The number of links and switches match "\
2991 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002992 result = main.TRUE
2993 else:
You Wang24139872016-05-03 11:48:47 -07002994 output = output + \
2995 "The number of links and switches does not match " + \
2996 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002997 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002998 output = output + "\n ONOS sees %i devices" % int( devices )
2999 output = output + " (%i expected) " % int( numoswitch )
3000 output = output + "and %i links " % int( links )
3001 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003002 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003003 output = output + "and %i controllers " % int( nodes )
3004 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003005 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003006 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003007 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003008 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003009 else:
You Wang24139872016-05-03 11:48:47 -07003010 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003011 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003012 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003013 main.log.error( self.name + ": EOF exception found" )
3014 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04003015 main.cleanup()
3016 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003017 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003018 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04003019 main.cleanup()
3020 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003021
kelvin-onlabd3b64892015-01-20 13:26:24 -08003022 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003023 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003024 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003025 deviceId must be the id of a device as seen in the onos devices command
3026 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003027 role must be either master, standby, or none
3028
Jon Halle3f39ff2015-01-13 11:50:53 -08003029 Returns:
3030 main.TRUE or main.FALSE based on argument verification and
3031 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003032 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003033 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003034 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003035 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003036 cmdStr = "device-role " +\
3037 str( deviceId ) + " " +\
3038 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003039 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003040 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003041 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003042 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003043 if re.search( "Error", handle ):
3044 # end color output to escape any colours
3045 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003046 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003047 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003048 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003049 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003050 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003051 main.log.error( "Invalid 'role' given to device_role(). " +
3052 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003053 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003054 except AssertionError:
3055 main.log.exception( "" )
3056 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003057 except TypeError:
3058 main.log.exception( self.name + ": Object not as expected" )
3059 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003060 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003061 main.log.error( self.name + ": EOF exception found" )
3062 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04003063 main.cleanup()
3064 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003065 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003066 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04003067 main.cleanup()
3068 main.exit()
3069
kelvin-onlabd3b64892015-01-20 13:26:24 -08003070 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003071 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003072 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003073 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003074 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003075 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003076 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003077 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003078 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003079 cmdStr += " -j"
3080 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003081 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003082 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003083 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003084 except AssertionError:
3085 main.log.exception( "" )
3086 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003087 except TypeError:
3088 main.log.exception( self.name + ": Object not as expected" )
3089 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003090 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003091 main.log.error( self.name + ": EOF exception found" )
3092 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003093 main.cleanup()
3094 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003095 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003096 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003097 main.cleanup()
3098 main.exit()
3099
kelvin-onlabd3b64892015-01-20 13:26:24 -08003100 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003101 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003102 CLI command to get the current leader for the Election test application
3103 NOTE: Requires installation of the onos-app-election feature
3104 Returns: Node IP of the leader if one exists
3105 None if none exists
3106 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003107 """
Jon Hall94fd0472014-12-08 11:52:42 -08003108 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003109 cmdStr = "election-test-leader"
3110 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003111 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003112 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003113 # Leader
3114 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003115 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003116 nodeSearch = re.search( leaderPattern, response )
3117 if nodeSearch:
3118 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003119 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003120 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003121 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003122 # no leader
3123 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003124 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003125 nullSearch = re.search( nullPattern, response )
3126 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003127 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003128 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003129 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003130 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003131 main.log.error( "Error in electionTestLeader on " + self.name +
3132 ": " + "unexpected response" )
3133 main.log.error( repr( response ) )
3134 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003135 except AssertionError:
3136 main.log.exception( "" )
3137 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003138 except TypeError:
3139 main.log.exception( self.name + ": Object not as expected" )
3140 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003141 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003142 main.log.error( self.name + ": EOF exception found" )
3143 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003144 main.cleanup()
3145 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003146 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003147 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003148 main.cleanup()
3149 main.exit()
3150
kelvin-onlabd3b64892015-01-20 13:26:24 -08003151 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003152 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003153 CLI command to run for leadership of the Election test application.
3154 NOTE: Requires installation of the onos-app-election feature
3155 Returns: Main.TRUE on success
3156 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003157 """
Jon Hall94fd0472014-12-08 11:52:42 -08003158 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003159 cmdStr = "election-test-run"
3160 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003161 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003162 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003163 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003164 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003165 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003166 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003167 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003168 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003169 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003170 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003171 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003172 main.log.error( "Error in electionTestRun on " + self.name +
3173 ": " + "unexpected response" )
3174 main.log.error( repr( response ) )
3175 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003176 except AssertionError:
3177 main.log.exception( "" )
3178 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003179 except TypeError:
3180 main.log.exception( self.name + ": Object not as expected" )
3181 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003182 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003183 main.log.error( self.name + ": EOF exception found" )
3184 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003185 main.cleanup()
3186 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003187 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003188 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003189 main.cleanup()
3190 main.exit()
3191
kelvin-onlabd3b64892015-01-20 13:26:24 -08003192 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003193 """
Jon Hall94fd0472014-12-08 11:52:42 -08003194 * CLI command to withdraw the local node from leadership election for
3195 * the Election test application.
3196 #NOTE: Requires installation of the onos-app-election feature
3197 Returns: Main.TRUE on success
3198 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003199 """
Jon Hall94fd0472014-12-08 11:52:42 -08003200 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003201 cmdStr = "election-test-withdraw"
3202 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003203 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003204 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003205 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003206 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003207 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003208 if re.search( successPattern, response ):
3209 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003210 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003211 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003212 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003213 main.log.error( "Error in electionTestWithdraw on " +
3214 self.name + ": " + "unexpected response" )
3215 main.log.error( repr( response ) )
3216 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003217 except AssertionError:
3218 main.log.exception( "" )
3219 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003220 except TypeError:
3221 main.log.exception( self.name + ": Object not as expected" )
3222 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003223 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003224 main.log.error( self.name + ": EOF exception found" )
3225 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003226 main.cleanup()
3227 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003228 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003229 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003230 main.cleanup()
3231 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003232
kelvin8ec71442015-01-15 16:57:00 -08003233 def getDevicePortsEnabledCount( self, dpid ):
3234 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003235 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003236 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003237 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003238 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003239 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3240 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003241 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003242 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003243 if re.search( "No such device", output ):
3244 main.log.error( "Error in getting ports" )
3245 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003246 return output
Jon Hallc6793552016-01-19 14:18:37 -08003247 except AssertionError:
3248 main.log.exception( "" )
3249 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003250 except TypeError:
3251 main.log.exception( self.name + ": Object not as expected" )
3252 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003253 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003254 main.log.error( self.name + ": EOF exception found" )
3255 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003256 main.cleanup()
3257 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003258 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003259 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003260 main.cleanup()
3261 main.exit()
3262
kelvin8ec71442015-01-15 16:57:00 -08003263 def getDeviceLinksActiveCount( self, dpid ):
3264 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003265 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003266 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003267 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003268 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003269 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3270 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003271 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003272 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003273 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003274 main.log.error( "Error in getting ports " )
3275 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003276 return output
Jon Hallc6793552016-01-19 14:18:37 -08003277 except AssertionError:
3278 main.log.exception( "" )
3279 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003280 except TypeError:
3281 main.log.exception( self.name + ": Object not as expected" )
3282 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003283 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003284 main.log.error( self.name + ": EOF exception found" )
3285 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003286 main.cleanup()
3287 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003288 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003289 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003290 main.cleanup()
3291 main.exit()
3292
kelvin8ec71442015-01-15 16:57:00 -08003293 def getAllIntentIds( self ):
3294 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003295 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003296 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003297 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003298 cmdStr = "onos:intents | grep id="
3299 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003300 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003301 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003302 if re.search( "Error", output ):
3303 main.log.error( "Error in getting ports" )
3304 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003305 return output
Jon Hallc6793552016-01-19 14:18:37 -08003306 except AssertionError:
3307 main.log.exception( "" )
3308 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003309 except TypeError:
3310 main.log.exception( self.name + ": Object not as expected" )
3311 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003312 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003313 main.log.error( self.name + ": EOF exception found" )
3314 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003315 main.cleanup()
3316 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003317 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003318 main.log.exception( self.name + ": Uncaught exception!" )
3319 main.cleanup()
3320 main.exit()
3321
Jon Hall73509952015-02-24 16:42:56 -08003322 def intentSummary( self ):
3323 """
Jon Hallefbd9792015-03-05 16:11:36 -08003324 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003325 """
3326 try:
3327 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003328 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003329 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003330 states.append( intent.get( 'state', None ) )
3331 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003332 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003333 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003334 except ( TypeError, ValueError ):
3335 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003336 return None
3337 except pexpect.EOF:
3338 main.log.error( self.name + ": EOF exception found" )
3339 main.log.error( self.name + ": " + self.handle.before )
3340 main.cleanup()
3341 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003342 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003343 main.log.exception( self.name + ": Uncaught exception!" )
3344 main.cleanup()
3345 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003346
Jon Hall61282e32015-03-19 11:34:11 -07003347 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003348 """
3349 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003350 Optional argument:
3351 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003352 """
Jon Hall63604932015-02-26 17:09:50 -08003353 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003354 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003355 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003356 cmdStr += " -j"
3357 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003358 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003359 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003360 return output
Jon Hallc6793552016-01-19 14:18:37 -08003361 except AssertionError:
3362 main.log.exception( "" )
3363 return None
Jon Hall63604932015-02-26 17:09:50 -08003364 except TypeError:
3365 main.log.exception( self.name + ": Object not as expected" )
3366 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003367 except pexpect.EOF:
3368 main.log.error( self.name + ": EOF exception found" )
3369 main.log.error( self.name + ": " + self.handle.before )
3370 main.cleanup()
3371 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003372 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003373 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003374 main.cleanup()
3375 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003376
acsmarsa4a4d1e2015-07-10 16:01:24 -07003377 def leaderCandidates( self, jsonFormat=True ):
3378 """
3379 Returns the output of the leaders -c command.
3380 Optional argument:
3381 * jsonFormat - boolean indicating if you want output in json
3382 """
3383 try:
3384 cmdStr = "onos:leaders -c"
3385 if jsonFormat:
3386 cmdStr += " -j"
3387 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003388 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003389 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003390 return output
Jon Hallc6793552016-01-19 14:18:37 -08003391 except AssertionError:
3392 main.log.exception( "" )
3393 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003394 except TypeError:
3395 main.log.exception( self.name + ": Object not as expected" )
3396 return None
3397 except pexpect.EOF:
3398 main.log.error( self.name + ": EOF exception found" )
3399 main.log.error( self.name + ": " + self.handle.before )
3400 main.cleanup()
3401 main.exit()
3402 except Exception:
3403 main.log.exception( self.name + ": Uncaught exception!" )
3404 main.cleanup()
3405 main.exit()
3406
Jon Hallc6793552016-01-19 14:18:37 -08003407 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003408 """
3409 Returns a list in format [leader,candidate1,candidate2,...] for a given
3410 topic parameter and an empty list if the topic doesn't exist
3411 If no leader is elected leader in the returned list will be "none"
3412 Returns None if there is a type error processing the json object
3413 """
3414 try:
Jon Hall6e709752016-02-01 13:38:46 -08003415 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003416 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003417 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003418 assert "Command not found:" not in rawOutput, rawOutput
3419 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003420 results = []
3421 for dict in output:
3422 if dict["topic"] == topic:
3423 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003424 candidates = re.split( ", ", dict["candidates"][1:-1] )
3425 results.append( leader )
3426 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003427 return results
Jon Hallc6793552016-01-19 14:18:37 -08003428 except AssertionError:
3429 main.log.exception( "" )
3430 return None
3431 except ( TypeError, ValueError ):
3432 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003433 return None
3434 except pexpect.EOF:
3435 main.log.error( self.name + ": EOF exception found" )
3436 main.log.error( self.name + ": " + self.handle.before )
3437 main.cleanup()
3438 main.exit()
3439 except Exception:
3440 main.log.exception( self.name + ": Uncaught exception!" )
3441 main.cleanup()
3442 main.exit()
3443
Jon Hall61282e32015-03-19 11:34:11 -07003444 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003445 """
3446 Returns the output of the intent Pending map.
3447 """
Jon Hall63604932015-02-26 17:09:50 -08003448 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003449 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003450 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003451 cmdStr += " -j"
3452 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003453 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003454 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003455 return output
Jon Hallc6793552016-01-19 14:18:37 -08003456 except AssertionError:
3457 main.log.exception( "" )
3458 return None
Jon Hall63604932015-02-26 17:09:50 -08003459 except TypeError:
3460 main.log.exception( self.name + ": Object not as expected" )
3461 return None
3462 except pexpect.EOF:
3463 main.log.error( self.name + ": EOF exception found" )
3464 main.log.error( self.name + ": " + self.handle.before )
3465 main.cleanup()
3466 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003467 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003468 main.log.exception( self.name + ": Uncaught exception!" )
3469 main.cleanup()
3470 main.exit()
3471
Jon Hall2c8959e2016-12-16 12:17:34 -08003472 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003473 """
3474 Returns the output of the raft partitions command for ONOS.
3475 """
Jon Hall61282e32015-03-19 11:34:11 -07003476 # Sample JSON
3477 # {
3478 # "leader": "tcp://10.128.30.11:7238",
3479 # "members": [
3480 # "tcp://10.128.30.11:7238",
3481 # "tcp://10.128.30.17:7238",
3482 # "tcp://10.128.30.13:7238",
3483 # ],
3484 # "name": "p1",
3485 # "term": 3
3486 # },
Jon Hall63604932015-02-26 17:09:50 -08003487 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003488 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003489 if candidates:
3490 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003491 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003492 cmdStr += " -j"
3493 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003494 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003495 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003496 return output
Jon Hallc6793552016-01-19 14:18:37 -08003497 except AssertionError:
3498 main.log.exception( "" )
3499 return None
Jon Hall63604932015-02-26 17:09:50 -08003500 except TypeError:
3501 main.log.exception( self.name + ": Object not as expected" )
3502 return None
3503 except pexpect.EOF:
3504 main.log.error( self.name + ": EOF exception found" )
3505 main.log.error( self.name + ": " + self.handle.before )
3506 main.cleanup()
3507 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003508 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003509 main.log.exception( self.name + ": Uncaught exception!" )
3510 main.cleanup()
3511 main.exit()
3512
Jon Halle9f909e2016-09-23 10:43:12 -07003513 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003514 """
3515 Returns the output of the apps command for ONOS. This command lists
3516 information about installed ONOS applications
3517 """
3518 # Sample JSON object
3519 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3520 # "description":"ONOS OpenFlow protocol southbound providers",
3521 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3522 # "features":"[onos-openflow]","state":"ACTIVE"}]
3523 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003524 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003525 if summary:
3526 cmdStr += " -s"
3527 if active:
3528 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003529 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003530 cmdStr += " -j"
3531 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003532 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003533 assert "Command not found:" not in output, output
3534 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003535 return output
Jon Hallbe379602015-03-24 13:39:32 -07003536 # FIXME: look at specific exceptions/Errors
3537 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003538 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003539 return None
3540 except TypeError:
3541 main.log.exception( self.name + ": Object not as expected" )
3542 return None
3543 except pexpect.EOF:
3544 main.log.error( self.name + ": EOF exception found" )
3545 main.log.error( self.name + ": " + self.handle.before )
3546 main.cleanup()
3547 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003548 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003549 main.log.exception( self.name + ": Uncaught exception!" )
3550 main.cleanup()
3551 main.exit()
3552
Jon Hall146f1522015-03-24 15:33:24 -07003553 def appStatus( self, appName ):
3554 """
3555 Uses the onos:apps cli command to return the status of an application.
3556 Returns:
3557 "ACTIVE" - If app is installed and activated
3558 "INSTALLED" - If app is installed and deactivated
3559 "UNINSTALLED" - If app is not installed
3560 None - on error
3561 """
Jon Hall146f1522015-03-24 15:33:24 -07003562 try:
3563 if not isinstance( appName, types.StringType ):
3564 main.log.error( self.name + ".appStatus(): appName must be" +
3565 " a string" )
3566 return None
3567 output = self.apps( jsonFormat=True )
3568 appsJson = json.loads( output )
3569 state = None
3570 for app in appsJson:
3571 if appName == app.get('name'):
3572 state = app.get('state')
3573 break
3574 if state == "ACTIVE" or state == "INSTALLED":
3575 return state
3576 elif state is None:
3577 return "UNINSTALLED"
3578 elif state:
3579 main.log.error( "Unexpected state from 'onos:apps': " +
3580 str( state ) )
3581 return state
Jon Hallc6793552016-01-19 14:18:37 -08003582 except ( TypeError, ValueError ):
3583 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003584 return None
3585 except pexpect.EOF:
3586 main.log.error( self.name + ": EOF exception found" )
3587 main.log.error( self.name + ": " + self.handle.before )
3588 main.cleanup()
3589 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003590 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003591 main.log.exception( self.name + ": Uncaught exception!" )
3592 main.cleanup()
3593 main.exit()
3594
Jon Hallbe379602015-03-24 13:39:32 -07003595 def app( self, appName, option ):
3596 """
3597 Interacts with the app command for ONOS. This command manages
3598 application inventory.
3599 """
Jon Hallbe379602015-03-24 13:39:32 -07003600 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003601 # Validate argument types
3602 valid = True
3603 if not isinstance( appName, types.StringType ):
3604 main.log.error( self.name + ".app(): appName must be a " +
3605 "string" )
3606 valid = False
3607 if not isinstance( option, types.StringType ):
3608 main.log.error( self.name + ".app(): option must be a string" )
3609 valid = False
3610 if not valid:
3611 return main.FALSE
3612 # Validate Option
3613 option = option.lower()
3614 # NOTE: Install may become a valid option
3615 if option == "activate":
3616 pass
3617 elif option == "deactivate":
3618 pass
3619 elif option == "uninstall":
3620 pass
3621 else:
3622 # Invalid option
3623 main.log.error( "The ONOS app command argument only takes " +
3624 "the values: (activate|deactivate|uninstall)" +
3625 "; was given '" + option + "'")
3626 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003627 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003628 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003629 assert output is not None, "Error in sendline"
3630 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003631 if "Error executing command" in output:
3632 main.log.error( "Error in processing onos:app command: " +
3633 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003634 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003635 elif "No such application" in output:
3636 main.log.error( "The application '" + appName +
3637 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003638 return main.FALSE
3639 elif "Command not found:" in output:
3640 main.log.error( "Error in processing onos:app command: " +
3641 str( output ) )
3642 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003643 elif "Unsupported command:" in output:
3644 main.log.error( "Incorrect command given to 'app': " +
3645 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003646 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003647 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003648 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003649 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003650 except AssertionError:
3651 main.log.exception( self.name + ": AssertionError exception found" )
3652 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003653 except TypeError:
3654 main.log.exception( self.name + ": Object not as expected" )
3655 return main.ERROR
3656 except pexpect.EOF:
3657 main.log.error( self.name + ": EOF exception found" )
3658 main.log.error( self.name + ": " + self.handle.before )
3659 main.cleanup()
3660 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003661 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003662 main.log.exception( self.name + ": Uncaught exception!" )
3663 main.cleanup()
3664 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003665
Jon Hallbd16b922015-03-26 17:53:15 -07003666 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003667 """
3668 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003669 appName is the hierarchical app name, not the feature name
3670 If check is True, method will check the status of the app after the
3671 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003672 Returns main.TRUE if the command was successfully sent
3673 main.FALSE if the cli responded with an error or given
3674 incorrect input
3675 """
3676 try:
3677 if not isinstance( appName, types.StringType ):
3678 main.log.error( self.name + ".activateApp(): appName must be" +
3679 " a string" )
3680 return main.FALSE
3681 status = self.appStatus( appName )
3682 if status == "INSTALLED":
3683 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003684 if check and response == main.TRUE:
3685 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003686 status = self.appStatus( appName )
3687 if status == "ACTIVE":
3688 return main.TRUE
3689 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003690 main.log.debug( "The state of application " +
3691 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003692 time.sleep( 1 )
3693 return main.FALSE
3694 else: # not 'check' or command didn't succeed
3695 return response
Jon Hall146f1522015-03-24 15:33:24 -07003696 elif status == "ACTIVE":
3697 return main.TRUE
3698 elif status == "UNINSTALLED":
3699 main.log.error( self.name + ": Tried to activate the " +
3700 "application '" + appName + "' which is not " +
3701 "installed." )
3702 else:
3703 main.log.error( "Unexpected return value from appStatus: " +
3704 str( status ) )
3705 return main.ERROR
3706 except TypeError:
3707 main.log.exception( self.name + ": Object not as expected" )
3708 return main.ERROR
3709 except pexpect.EOF:
3710 main.log.error( self.name + ": EOF exception found" )
3711 main.log.error( self.name + ": " + self.handle.before )
3712 main.cleanup()
3713 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003714 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003715 main.log.exception( self.name + ": Uncaught exception!" )
3716 main.cleanup()
3717 main.exit()
3718
Jon Hallbd16b922015-03-26 17:53:15 -07003719 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003720 """
3721 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003722 appName is the hierarchical app name, not the feature name
3723 If check is True, method will check the status of the app after the
3724 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003725 Returns main.TRUE if the command was successfully sent
3726 main.FALSE if the cli responded with an error or given
3727 incorrect input
3728 """
3729 try:
3730 if not isinstance( appName, types.StringType ):
3731 main.log.error( self.name + ".deactivateApp(): appName must " +
3732 "be a string" )
3733 return main.FALSE
3734 status = self.appStatus( appName )
3735 if status == "INSTALLED":
3736 return main.TRUE
3737 elif status == "ACTIVE":
3738 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003739 if check and response == main.TRUE:
3740 for i in range(10): # try 10 times then give up
3741 status = self.appStatus( appName )
3742 if status == "INSTALLED":
3743 return main.TRUE
3744 else:
3745 time.sleep( 1 )
3746 return main.FALSE
3747 else: # not check or command didn't succeed
3748 return response
Jon Hall146f1522015-03-24 15:33:24 -07003749 elif status == "UNINSTALLED":
3750 main.log.warn( self.name + ": Tried to deactivate the " +
3751 "application '" + appName + "' which is not " +
3752 "installed." )
3753 return main.TRUE
3754 else:
3755 main.log.error( "Unexpected return value from appStatus: " +
3756 str( status ) )
3757 return main.ERROR
3758 except TypeError:
3759 main.log.exception( self.name + ": Object not as expected" )
3760 return main.ERROR
3761 except pexpect.EOF:
3762 main.log.error( self.name + ": EOF exception found" )
3763 main.log.error( self.name + ": " + self.handle.before )
3764 main.cleanup()
3765 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003766 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003767 main.log.exception( self.name + ": Uncaught exception!" )
3768 main.cleanup()
3769 main.exit()
3770
Jon Hallbd16b922015-03-26 17:53:15 -07003771 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003772 """
3773 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003774 appName is the hierarchical app name, not the feature name
3775 If check is True, method will check the status of the app after the
3776 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003777 Returns main.TRUE if the command was successfully sent
3778 main.FALSE if the cli responded with an error or given
3779 incorrect input
3780 """
3781 # TODO: check with Thomas about the state machine for apps
3782 try:
3783 if not isinstance( appName, types.StringType ):
3784 main.log.error( self.name + ".uninstallApp(): appName must " +
3785 "be a string" )
3786 return main.FALSE
3787 status = self.appStatus( appName )
3788 if status == "INSTALLED":
3789 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003790 if check and response == main.TRUE:
3791 for i in range(10): # try 10 times then give up
3792 status = self.appStatus( appName )
3793 if status == "UNINSTALLED":
3794 return main.TRUE
3795 else:
3796 time.sleep( 1 )
3797 return main.FALSE
3798 else: # not check or command didn't succeed
3799 return response
Jon Hall146f1522015-03-24 15:33:24 -07003800 elif status == "ACTIVE":
3801 main.log.warn( self.name + ": Tried to uninstall the " +
3802 "application '" + appName + "' which is " +
3803 "currently active." )
3804 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003805 if check and response == main.TRUE:
3806 for i in range(10): # try 10 times then give up
3807 status = self.appStatus( appName )
3808 if status == "UNINSTALLED":
3809 return main.TRUE
3810 else:
3811 time.sleep( 1 )
3812 return main.FALSE
3813 else: # not check or command didn't succeed
3814 return response
Jon Hall146f1522015-03-24 15:33:24 -07003815 elif status == "UNINSTALLED":
3816 return main.TRUE
3817 else:
3818 main.log.error( "Unexpected return value from appStatus: " +
3819 str( status ) )
3820 return main.ERROR
3821 except TypeError:
3822 main.log.exception( self.name + ": Object not as expected" )
3823 return main.ERROR
3824 except pexpect.EOF:
3825 main.log.error( self.name + ": EOF exception found" )
3826 main.log.error( self.name + ": " + self.handle.before )
3827 main.cleanup()
3828 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003829 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003830 main.log.exception( self.name + ": Uncaught exception!" )
3831 main.cleanup()
3832 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003833
3834 def appIDs( self, jsonFormat=True ):
3835 """
3836 Show the mappings between app id and app names given by the 'app-ids'
3837 cli command
3838 """
3839 try:
3840 cmdStr = "app-ids"
3841 if jsonFormat:
3842 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003843 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003844 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003845 assert "Command not found:" not in output, output
3846 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003847 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003848 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003849 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003850 return None
3851 except TypeError:
3852 main.log.exception( self.name + ": Object not as expected" )
3853 return None
3854 except pexpect.EOF:
3855 main.log.error( self.name + ": EOF exception found" )
3856 main.log.error( self.name + ": " + self.handle.before )
3857 main.cleanup()
3858 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003859 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003860 main.log.exception( self.name + ": Uncaught exception!" )
3861 main.cleanup()
3862 main.exit()
3863
3864 def appToIDCheck( self ):
3865 """
3866 This method will check that each application's ID listed in 'apps' is
3867 the same as the ID listed in 'app-ids'. The check will also check that
3868 there are no duplicate IDs issued. Note that an app ID should be
3869 a globaly unique numerical identifier for app/app-like features. Once
3870 an ID is registered, the ID is never freed up so that if an app is
3871 reinstalled it will have the same ID.
3872
3873 Returns: main.TRUE if the check passes and
3874 main.FALSE if the check fails or
3875 main.ERROR if there is some error in processing the test
3876 """
3877 try:
Jon Hall390696c2015-05-05 17:13:41 -07003878 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003879 rawJson = self.appIDs( jsonFormat=True )
3880 if rawJson:
3881 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003882 else:
Jon Hallc6793552016-01-19 14:18:37 -08003883 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003884 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003885 rawJson = self.apps( jsonFormat=True )
3886 if rawJson:
3887 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003888 else:
Jon Hallc6793552016-01-19 14:18:37 -08003889 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003890 bail = True
3891 if bail:
3892 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003893 result = main.TRUE
3894 for app in apps:
3895 appID = app.get( 'id' )
3896 if appID is None:
3897 main.log.error( "Error parsing app: " + str( app ) )
3898 result = main.FALSE
3899 appName = app.get( 'name' )
3900 if appName is None:
3901 main.log.error( "Error parsing app: " + str( app ) )
3902 result = main.FALSE
3903 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003904 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003905 # main.log.debug( "Comparing " + str( app ) + " to " +
3906 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003907 if not current: # if ids doesn't have this id
3908 result = main.FALSE
3909 main.log.error( "'app-ids' does not have the ID for " +
3910 str( appName ) + " that apps does." )
3911 elif len( current ) > 1:
3912 # there is more than one app with this ID
3913 result = main.FALSE
3914 # We will log this later in the method
3915 elif not current[0][ 'name' ] == appName:
3916 currentName = current[0][ 'name' ]
3917 result = main.FALSE
3918 main.log.error( "'app-ids' has " + str( currentName ) +
3919 " registered under id:" + str( appID ) +
3920 " but 'apps' has " + str( appName ) )
3921 else:
3922 pass # id and name match!
3923 # now make sure that app-ids has no duplicates
3924 idsList = []
3925 namesList = []
3926 for item in ids:
3927 idsList.append( item[ 'id' ] )
3928 namesList.append( item[ 'name' ] )
3929 if len( idsList ) != len( set( idsList ) ) or\
3930 len( namesList ) != len( set( namesList ) ):
3931 main.log.error( "'app-ids' has some duplicate entries: \n"
3932 + json.dumps( ids,
3933 sort_keys=True,
3934 indent=4,
3935 separators=( ',', ': ' ) ) )
3936 result = main.FALSE
3937 return result
Jon Hallc6793552016-01-19 14:18:37 -08003938 except ( TypeError, ValueError ):
3939 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003940 return main.ERROR
3941 except pexpect.EOF:
3942 main.log.error( self.name + ": EOF exception found" )
3943 main.log.error( self.name + ": " + self.handle.before )
3944 main.cleanup()
3945 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003946 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003947 main.log.exception( self.name + ": Uncaught exception!" )
3948 main.cleanup()
3949 main.exit()
3950
Jon Hallfb760a02015-04-13 15:35:03 -07003951 def getCfg( self, component=None, propName=None, short=False,
3952 jsonFormat=True ):
3953 """
3954 Get configuration settings from onos cli
3955 Optional arguments:
3956 component - Optionally only list configurations for a specific
3957 component. If None, all components with configurations
3958 are displayed. Case Sensitive string.
3959 propName - If component is specified, propName option will show
3960 only this specific configuration from that component.
3961 Case Sensitive string.
3962 jsonFormat - Returns output as json. Note that this will override
3963 the short option
3964 short - Short, less verbose, version of configurations.
3965 This is overridden by the json option
3966 returns:
3967 Output from cli as a string or None on error
3968 """
3969 try:
3970 baseStr = "cfg"
3971 cmdStr = " get"
3972 componentStr = ""
3973 if component:
3974 componentStr += " " + component
3975 if propName:
3976 componentStr += " " + propName
3977 if jsonFormat:
3978 baseStr += " -j"
3979 elif short:
3980 baseStr += " -s"
3981 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003982 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003983 assert "Command not found:" not in output, output
3984 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003985 return output
3986 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003987 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003988 return None
3989 except TypeError:
3990 main.log.exception( self.name + ": Object not as expected" )
3991 return None
3992 except pexpect.EOF:
3993 main.log.error( self.name + ": EOF exception found" )
3994 main.log.error( self.name + ": " + self.handle.before )
3995 main.cleanup()
3996 main.exit()
3997 except Exception:
3998 main.log.exception( self.name + ": Uncaught exception!" )
3999 main.cleanup()
4000 main.exit()
4001
4002 def setCfg( self, component, propName, value=None, check=True ):
4003 """
4004 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004005 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004006 component - The case sensitive name of the component whose
4007 property is to be set
4008 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004009 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004010 value - The value to set the property to. If None, will unset the
4011 property and revert it to it's default value(if applicable)
4012 check - Boolean, Check whether the option was successfully set this
4013 only applies when a value is given.
4014 returns:
4015 main.TRUE on success or main.FALSE on failure. If check is False,
4016 will return main.TRUE unless there is an error
4017 """
4018 try:
4019 baseStr = "cfg"
4020 cmdStr = " set " + str( component ) + " " + str( propName )
4021 if value is not None:
4022 cmdStr += " " + str( value )
4023 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004024 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004025 assert "Command not found:" not in output, output
4026 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004027 if value and check:
4028 results = self.getCfg( component=str( component ),
4029 propName=str( propName ),
4030 jsonFormat=True )
4031 # Check if current value is what we just set
4032 try:
4033 jsonOutput = json.loads( results )
4034 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004035 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004036 main.log.exception( "Error parsing cfg output" )
4037 main.log.error( "output:" + repr( results ) )
4038 return main.FALSE
4039 if current == str( value ):
4040 return main.TRUE
4041 return main.FALSE
4042 return main.TRUE
4043 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004044 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004045 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004046 except ( TypeError, ValueError ):
4047 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004048 return main.FALSE
4049 except pexpect.EOF:
4050 main.log.error( self.name + ": EOF exception found" )
4051 main.log.error( self.name + ": " + self.handle.before )
4052 main.cleanup()
4053 main.exit()
4054 except Exception:
4055 main.log.exception( self.name + ": Uncaught exception!" )
4056 main.cleanup()
4057 main.exit()
4058
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004059 def distPrimitivesSend( self, cmd ):
4060 """
4061 Function to handle sending cli commands for the distributed primitives test app
4062
4063 This command will catch some exceptions and retry the command on some
4064 specific store exceptions.
4065
4066 Required arguments:
4067 cmd - The command to send to the cli
4068 returns:
4069 string containing the cli output
4070 None on Error
4071 """
4072 try:
4073 output = self.sendline( cmd )
4074 try:
4075 assert output is not None, "Error in sendline"
4076 # TODO: Maybe make this less hardcoded
4077 # ConsistentMap Exceptions
4078 assert "org.onosproject.store.service" not in output
4079 # Node not leader
4080 assert "java.lang.IllegalStateException" not in output
4081 except AssertionError:
4082 main.log.error( "Error in processing '" + cmd + "' " +
4083 "command: " + str( output ) )
4084 retryTime = 30 # Conservative time, given by Madan
4085 main.log.info( "Waiting " + str( retryTime ) +
4086 "seconds before retrying." )
4087 time.sleep( retryTime ) # Due to change in mastership
4088 output = self.sendline( cmd )
4089 assert output is not None, "Error in sendline"
4090 assert "Command not found:" not in output, output
4091 assert "Error executing command" not in output, output
4092 main.log.info( self.name + ": " + output )
4093 return output
4094 except AssertionError:
4095 main.log.exception( "Error in processing '" + cmd + "' command." )
4096 return None
4097 except TypeError:
4098 main.log.exception( self.name + ": Object not as expected" )
4099 return None
4100 except pexpect.EOF:
4101 main.log.error( self.name + ": EOF exception found" )
4102 main.log.error( self.name + ": " + self.handle.before )
4103 main.cleanup()
4104 main.exit()
4105 except Exception:
4106 main.log.exception( self.name + ": Uncaught exception!" )
4107 main.cleanup()
4108 main.exit()
4109
Jon Hall390696c2015-05-05 17:13:41 -07004110 def setTestAdd( self, setName, values ):
4111 """
4112 CLI command to add elements to a distributed set.
4113 Arguments:
4114 setName - The name of the set to add to.
4115 values - The value(s) to add to the set, space seperated.
4116 Example usages:
4117 setTestAdd( "set1", "a b c" )
4118 setTestAdd( "set2", "1" )
4119 returns:
4120 main.TRUE on success OR
4121 main.FALSE if elements were already in the set OR
4122 main.ERROR on error
4123 """
4124 try:
4125 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004126 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004127 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4128 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jon Hall390696c2015-05-05 17:13:41 -07004129 if re.search( positiveMatch, output):
4130 return main.TRUE
4131 elif re.search( negativeMatch, output):
4132 return main.FALSE
4133 else:
4134 main.log.error( self.name + ": setTestAdd did not" +
4135 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004136 main.log.debug( self.name + " actual: " + repr( output ) )
4137 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004138 except TypeError:
4139 main.log.exception( self.name + ": Object not as expected" )
4140 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004141 except Exception:
4142 main.log.exception( self.name + ": Uncaught exception!" )
4143 main.cleanup()
4144 main.exit()
4145
4146 def setTestRemove( self, setName, values, clear=False, retain=False ):
4147 """
4148 CLI command to remove elements from a distributed set.
4149 Required arguments:
4150 setName - The name of the set to remove from.
4151 values - The value(s) to remove from the set, space seperated.
4152 Optional arguments:
4153 clear - Clear all elements from the set
4154 retain - Retain only the given values. (intersection of the
4155 original set and the given set)
4156 returns:
4157 main.TRUE on success OR
4158 main.FALSE if the set was not changed OR
4159 main.ERROR on error
4160 """
4161 try:
4162 cmdStr = "set-test-remove "
4163 if clear:
4164 cmdStr += "-c " + str( setName )
4165 elif retain:
4166 cmdStr += "-r " + str( setName ) + " " + str( values )
4167 else:
4168 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004169 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004170 if clear:
4171 pattern = "Set " + str( setName ) + " cleared"
4172 if re.search( pattern, output ):
4173 return main.TRUE
4174 elif retain:
4175 positivePattern = str( setName ) + " was pruned to contain " +\
4176 "only elements of set \[(.*)\]"
4177 negativePattern = str( setName ) + " was not changed by " +\
4178 "retaining only elements of the set " +\
4179 "\[(.*)\]"
4180 if re.search( positivePattern, output ):
4181 return main.TRUE
4182 elif re.search( negativePattern, output ):
4183 return main.FALSE
4184 else:
4185 positivePattern = "\[(.*)\] was removed from the set " +\
4186 str( setName )
4187 if ( len( values.split() ) == 1 ):
4188 negativePattern = "\[(.*)\] was not in set " +\
4189 str( setName )
4190 else:
4191 negativePattern = "No element of \[(.*)\] was in set " +\
4192 str( setName )
4193 if re.search( positivePattern, output ):
4194 return main.TRUE
4195 elif re.search( negativePattern, output ):
4196 return main.FALSE
4197 main.log.error( self.name + ": setTestRemove did not" +
4198 " match expected output" )
4199 main.log.debug( self.name + " expected: " + pattern )
4200 main.log.debug( self.name + " actual: " + repr( output ) )
4201 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004202 except TypeError:
4203 main.log.exception( self.name + ": Object not as expected" )
4204 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004205 except Exception:
4206 main.log.exception( self.name + ": Uncaught exception!" )
4207 main.cleanup()
4208 main.exit()
4209
4210 def setTestGet( self, setName, values="" ):
4211 """
4212 CLI command to get the elements in a distributed set.
4213 Required arguments:
4214 setName - The name of the set to remove from.
4215 Optional arguments:
4216 values - The value(s) to check if in the set, space seperated.
4217 returns:
4218 main.ERROR on error OR
4219 A list of elements in the set if no optional arguments are
4220 supplied OR
4221 A tuple containing the list then:
4222 main.FALSE if the given values are not in the set OR
4223 main.TRUE if the given values are in the set OR
4224 """
4225 try:
4226 values = str( values ).strip()
4227 setName = str( setName ).strip()
4228 length = len( values.split() )
4229 containsCheck = None
4230 # Patterns to match
4231 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004232 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004233 containsTrue = "Set " + setName + " contains the value " + values
4234 containsFalse = "Set " + setName + " did not contain the value " +\
4235 values
4236 containsAllTrue = "Set " + setName + " contains the the subset " +\
4237 setPattern
4238 containsAllFalse = "Set " + setName + " did not contain the the" +\
4239 " subset " + setPattern
4240
4241 cmdStr = "set-test-get "
4242 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004243 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004244 if length == 0:
4245 match = re.search( pattern, output )
4246 else: # if given values
4247 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004248 patternTrue = pattern + "\r\n" + containsTrue
4249 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004250 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004251 patternTrue = pattern + "\r\n" + containsAllTrue
4252 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004253 matchTrue = re.search( patternTrue, output )
4254 matchFalse = re.search( patternFalse, output )
4255 if matchTrue:
4256 containsCheck = main.TRUE
4257 match = matchTrue
4258 elif matchFalse:
4259 containsCheck = main.FALSE
4260 match = matchFalse
4261 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004262 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004263 "expected output" )
4264 main.log.debug( self.name + " expected: " + pattern )
4265 main.log.debug( self.name + " actual: " + repr( output ) )
4266 match = None
4267 if match:
4268 setMatch = match.group( 1 )
4269 if setMatch == '':
4270 setList = []
4271 else:
4272 setList = setMatch.split( ", " )
4273 if length > 0:
4274 return ( setList, containsCheck )
4275 else:
4276 return setList
4277 else: # no match
4278 main.log.error( self.name + ": setTestGet did not" +
4279 " match expected output" )
4280 main.log.debug( self.name + " expected: " + pattern )
4281 main.log.debug( self.name + " actual: " + repr( output ) )
4282 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004283 except TypeError:
4284 main.log.exception( self.name + ": Object not as expected" )
4285 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004286 except Exception:
4287 main.log.exception( self.name + ": Uncaught exception!" )
4288 main.cleanup()
4289 main.exit()
4290
4291 def setTestSize( self, setName ):
4292 """
4293 CLI command to get the elements in a distributed set.
4294 Required arguments:
4295 setName - The name of the set to remove from.
4296 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004297 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004298 None on error
4299 """
4300 try:
4301 # TODO: Should this check against the number of elements returned
4302 # and then return true/false based on that?
4303 setName = str( setName ).strip()
4304 # Patterns to match
4305 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004306 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004307 setPattern
4308 cmdStr = "set-test-get -s "
4309 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004310 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004311 match = re.search( pattern, output )
4312 if match:
4313 setSize = int( match.group( 1 ) )
4314 setMatch = match.group( 2 )
4315 if len( setMatch.split() ) == setSize:
4316 main.log.info( "The size returned by " + self.name +
4317 " matches the number of elements in " +
4318 "the returned set" )
4319 else:
4320 main.log.error( "The size returned by " + self.name +
4321 " does not match the number of " +
4322 "elements in the returned set." )
4323 return setSize
4324 else: # no match
4325 main.log.error( self.name + ": setTestGet did not" +
4326 " match expected output" )
4327 main.log.debug( self.name + " expected: " + pattern )
4328 main.log.debug( self.name + " actual: " + repr( output ) )
4329 return None
Jon Hall390696c2015-05-05 17:13:41 -07004330 except TypeError:
4331 main.log.exception( self.name + ": Object not as expected" )
4332 return None
Jon Hall390696c2015-05-05 17:13:41 -07004333 except Exception:
4334 main.log.exception( self.name + ": Uncaught exception!" )
4335 main.cleanup()
4336 main.exit()
4337
Jon Hall80daded2015-05-27 16:07:00 -07004338 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004339 """
4340 Command to list the various counters in the system.
4341 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004342 if jsonFormat, a string of the json object returned by the cli
4343 command
4344 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004345 None on error
4346 """
Jon Hall390696c2015-05-05 17:13:41 -07004347 try:
Jon Hall390696c2015-05-05 17:13:41 -07004348 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004349 if jsonFormat:
4350 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004351 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004352 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004353 assert "Command not found:" not in output, output
4354 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004355 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004356 return output
Jon Hall390696c2015-05-05 17:13:41 -07004357 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004358 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004359 return None
Jon Hall390696c2015-05-05 17:13:41 -07004360 except TypeError:
4361 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004362 return None
Jon Hall390696c2015-05-05 17:13:41 -07004363 except pexpect.EOF:
4364 main.log.error( self.name + ": EOF exception found" )
4365 main.log.error( self.name + ": " + self.handle.before )
4366 main.cleanup()
4367 main.exit()
4368 except Exception:
4369 main.log.exception( self.name + ": Uncaught exception!" )
4370 main.cleanup()
4371 main.exit()
4372
Jon Hall935db192016-04-19 00:22:04 -07004373 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004374 """
Jon Halle1a3b752015-07-22 13:02:46 -07004375 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004376 Required arguments:
4377 counter - The name of the counter to increment.
4378 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004379 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004380 returns:
4381 integer value of the counter or
4382 None on Error
4383 """
4384 try:
4385 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004386 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004387 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004388 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004389 if delta != 1:
4390 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004391 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004392 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004393 match = re.search( pattern, output )
4394 if match:
4395 return int( match.group( 1 ) )
4396 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004397 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004398 " match expected output." )
4399 main.log.debug( self.name + " expected: " + pattern )
4400 main.log.debug( self.name + " actual: " + repr( output ) )
4401 return None
Jon Hall390696c2015-05-05 17:13:41 -07004402 except TypeError:
4403 main.log.exception( self.name + ": Object not as expected" )
4404 return None
Jon Hall390696c2015-05-05 17:13:41 -07004405 except Exception:
4406 main.log.exception( self.name + ": Uncaught exception!" )
4407 main.cleanup()
4408 main.exit()
4409
Jon Hall935db192016-04-19 00:22:04 -07004410 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004411 """
4412 CLI command to get a distributed counter then add a delta to it.
4413 Required arguments:
4414 counter - The name of the counter to increment.
4415 Optional arguments:
4416 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004417 returns:
4418 integer value of the counter or
4419 None on Error
4420 """
4421 try:
4422 counter = str( counter )
4423 delta = int( delta )
4424 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004425 cmdStr += counter
4426 if delta != 1:
4427 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004428 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004429 pattern = counter + " was updated to (-?\d+)"
4430 match = re.search( pattern, output )
4431 if match:
4432 return int( match.group( 1 ) )
4433 else:
4434 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4435 " match expected output." )
4436 main.log.debug( self.name + " expected: " + pattern )
4437 main.log.debug( self.name + " actual: " + repr( output ) )
4438 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004439 except TypeError:
4440 main.log.exception( self.name + ": Object not as expected" )
4441 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004442 except Exception:
4443 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle1a3b752015-07-22 13:02:46 -07004444 main.cleanup()
4445 main.exit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004446
4447 def valueTestGet( self, valueName ):
4448 """
4449 CLI command to get the value of an atomic value.
4450 Required arguments:
4451 valueName - The name of the value to get.
4452 returns:
4453 string value of the value or
4454 None on Error
4455 """
4456 try:
4457 valueName = str( valueName )
4458 cmdStr = "value-test "
4459 operation = "get"
4460 cmdStr = "value-test {} {}".format( valueName,
4461 operation )
4462 output = self.distPrimitivesSend( cmdStr )
4463 pattern = "(\w+)"
4464 match = re.search( pattern, output )
4465 if match:
4466 return match.group( 1 )
4467 else:
4468 main.log.error( self.name + ": valueTestGet did not" +
4469 " match expected output." )
4470 main.log.debug( self.name + " expected: " + pattern )
4471 main.log.debug( self.name + " actual: " + repr( output ) )
4472 return None
4473 except TypeError:
4474 main.log.exception( self.name + ": Object not as expected" )
4475 return None
4476 except Exception:
4477 main.log.exception( self.name + ": Uncaught exception!" )
4478 main.cleanup()
4479 main.exit()
4480
4481 def valueTestSet( self, valueName, newValue ):
4482 """
4483 CLI command to set the value of an atomic value.
4484 Required arguments:
4485 valueName - The name of the value to set.
4486 newValue - The value to assign to the given value.
4487 returns:
4488 main.TRUE on success or
4489 main.ERROR on Error
4490 """
4491 try:
4492 valueName = str( valueName )
4493 newValue = str( newValue )
4494 operation = "set"
4495 cmdStr = "value-test {} {} {}".format( valueName,
4496 operation,
4497 newValue )
4498 output = self.distPrimitivesSend( cmdStr )
4499 if output is not None:
4500 return main.TRUE
4501 else:
4502 return main.ERROR
4503 except TypeError:
4504 main.log.exception( self.name + ": Object not as expected" )
4505 return main.ERROR
4506 except Exception:
4507 main.log.exception( self.name + ": Uncaught exception!" )
4508 main.cleanup()
4509 main.exit()
4510
4511 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4512 """
4513 CLI command to compareAndSet the value of an atomic value.
4514 Required arguments:
4515 valueName - The name of the value.
4516 oldValue - Compare the current value of the atomic value to this
4517 newValue - If the value equals oldValue, set the value to newValue
4518 returns:
4519 main.TRUE on success or
4520 main.FALSE on failure or
4521 main.ERROR on Error
4522 """
4523 try:
4524 valueName = str( valueName )
4525 oldValue = str( oldValue )
4526 newValue = str( newValue )
4527 operation = "compareAndSet"
4528 cmdStr = "value-test {} {} {} {}".format( valueName,
4529 operation,
4530 oldValue,
4531 newValue )
4532 output = self.distPrimitivesSend( cmdStr )
4533 pattern = "(\w+)"
4534 match = re.search( pattern, output )
4535 if match:
4536 result = match.group( 1 )
4537 if result == "true":
4538 return main.TRUE
4539 elif result == "false":
4540 return main.FALSE
4541 else:
4542 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4543 " match expected output." )
4544 main.log.debug( self.name + " expected: " + pattern )
4545 main.log.debug( self.name + " actual: " + repr( output ) )
4546 return main.ERROR
4547 except TypeError:
4548 main.log.exception( self.name + ": Object not as expected" )
4549 return main.ERROR
4550 except Exception:
4551 main.log.exception( self.name + ": Uncaught exception!" )
4552 main.cleanup()
4553 main.exit()
4554
4555 def valueTestGetAndSet( self, valueName, newValue ):
4556 """
4557 CLI command to getAndSet the value of an atomic value.
4558 Required arguments:
4559 valueName - The name of the value to get.
4560 newValue - The value to assign to the given value
4561 returns:
4562 string value of the value or
4563 None on Error
4564 """
4565 try:
4566 valueName = str( valueName )
4567 cmdStr = "value-test "
4568 operation = "getAndSet"
4569 cmdStr += valueName + " " + operation
4570 cmdStr = "value-test {} {} {}".format( valueName,
4571 operation,
4572 newValue )
4573 output = self.distPrimitivesSend( cmdStr )
4574 pattern = "(\w+)"
4575 match = re.search( pattern, output )
4576 if match:
4577 return match.group( 1 )
4578 else:
4579 main.log.error( self.name + ": valueTestGetAndSet did not" +
4580 " match expected output." )
4581 main.log.debug( self.name + " expected: " + pattern )
4582 main.log.debug( self.name + " actual: " + repr( output ) )
4583 return None
4584 except TypeError:
4585 main.log.exception( self.name + ": Object not as expected" )
4586 return None
4587 except Exception:
4588 main.log.exception( self.name + ": Uncaught exception!" )
4589 main.cleanup()
4590 main.exit()
4591
4592 def valueTestDestroy( self, valueName ):
4593 """
4594 CLI command to destroy an atomic value.
4595 Required arguments:
4596 valueName - The name of the value to destroy.
4597 returns:
4598 main.TRUE on success or
4599 main.ERROR on Error
4600 """
4601 try:
4602 valueName = str( valueName )
4603 cmdStr = "value-test "
4604 operation = "destroy"
4605 cmdStr += valueName + " " + operation
4606 output = self.distPrimitivesSend( cmdStr )
4607 if output is not None:
4608 return main.TRUE
4609 else:
4610 return main.ERROR
4611 except TypeError:
4612 main.log.exception( self.name + ": Object not as expected" )
4613 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004614 except Exception:
4615 main.log.exception( self.name + ": Uncaught exception!" )
4616 main.cleanup()
4617 main.exit()
4618
YPZhangfebf7302016-05-24 16:45:56 -07004619 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004620 """
4621 Description: Execute summary command in onos
4622 Returns: json object ( summary -j ), returns main.FALSE if there is
4623 no output
4624
4625 """
4626 try:
4627 cmdStr = "summary"
4628 if jsonFormat:
4629 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004630 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004631 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004632 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004633 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004634 if not handle:
4635 main.log.error( self.name + ": There is no output in " +
4636 "summary command" )
4637 return main.FALSE
4638 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004639 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004640 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004641 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004642 except TypeError:
4643 main.log.exception( self.name + ": Object not as expected" )
4644 return None
4645 except pexpect.EOF:
4646 main.log.error( self.name + ": EOF exception found" )
4647 main.log.error( self.name + ": " + self.handle.before )
4648 main.cleanup()
4649 main.exit()
4650 except Exception:
4651 main.log.exception( self.name + ": Uncaught exception!" )
4652 main.cleanup()
4653 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004654
Jon Hall935db192016-04-19 00:22:04 -07004655 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004656 """
4657 CLI command to get the value of a key in a consistent map using
4658 transactions. This a test function and can only get keys from the
4659 test map hard coded into the cli command
4660 Required arguments:
4661 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004662 returns:
4663 The string value of the key or
4664 None on Error
4665 """
4666 try:
4667 keyName = str( keyName )
4668 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004669 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004670 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004671 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4672 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004673 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004674 return None
4675 else:
4676 match = re.search( pattern, output )
4677 if match:
4678 return match.groupdict()[ 'value' ]
4679 else:
4680 main.log.error( self.name + ": transactionlMapGet did not" +
4681 " match expected output." )
4682 main.log.debug( self.name + " expected: " + pattern )
4683 main.log.debug( self.name + " actual: " + repr( output ) )
4684 return None
4685 except TypeError:
4686 main.log.exception( self.name + ": Object not as expected" )
4687 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004688 except Exception:
4689 main.log.exception( self.name + ": Uncaught exception!" )
4690 main.cleanup()
4691 main.exit()
4692
Jon Hall935db192016-04-19 00:22:04 -07004693 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004694 """
4695 CLI command to put a value into 'numKeys' number of keys in a
4696 consistent map using transactions. This a test function and can only
4697 put into keys named 'Key#' of the test map hard coded into the cli command
4698 Required arguments:
4699 numKeys - Number of keys to add the value to
4700 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004701 returns:
4702 A dictionary whose keys are the name of the keys put into the map
4703 and the values of the keys are dictionaries whose key-values are
4704 'value': value put into map and optionaly
4705 'oldValue': Previous value in the key or
4706 None on Error
4707
4708 Example output
4709 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4710 'Key2': {'value': 'Testing'} }
4711 """
4712 try:
4713 numKeys = str( numKeys )
4714 value = str( value )
4715 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004716 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004717 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004718 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4719 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4720 results = {}
4721 for line in output.splitlines():
4722 new = re.search( newPattern, line )
4723 updated = re.search( updatedPattern, line )
4724 if new:
4725 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4726 elif updated:
4727 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004728 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004729 else:
4730 main.log.error( self.name + ": transactionlMapGet did not" +
4731 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004732 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4733 newPattern,
4734 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004735 main.log.debug( self.name + " actual: " + repr( output ) )
4736 return results
4737 except TypeError:
4738 main.log.exception( self.name + ": Object not as expected" )
4739 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004740 except Exception:
4741 main.log.exception( self.name + ": Uncaught exception!" )
4742 main.cleanup()
4743 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004744
acsmarsdaea66c2015-09-03 11:44:06 -07004745 def maps( self, jsonFormat=True ):
4746 """
4747 Description: Returns result of onos:maps
4748 Optional:
4749 * jsonFormat: enable json formatting of output
4750 """
4751 try:
4752 cmdStr = "maps"
4753 if jsonFormat:
4754 cmdStr += " -j"
4755 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004756 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004757 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004758 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004759 except AssertionError:
4760 main.log.exception( "" )
4761 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004762 except TypeError:
4763 main.log.exception( self.name + ": Object not as expected" )
4764 return None
4765 except pexpect.EOF:
4766 main.log.error( self.name + ": EOF exception found" )
4767 main.log.error( self.name + ": " + self.handle.before )
4768 main.cleanup()
4769 main.exit()
4770 except Exception:
4771 main.log.exception( self.name + ": Uncaught exception!" )
4772 main.cleanup()
4773 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004774
4775 def getSwController( self, uri, jsonFormat=True ):
4776 """
4777 Descrition: Gets the controller information from the device
4778 """
4779 try:
4780 cmd = "device-controllers "
4781 if jsonFormat:
4782 cmd += "-j "
4783 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004784 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004785 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004786 return response
Jon Hallc6793552016-01-19 14:18:37 -08004787 except AssertionError:
4788 main.log.exception( "" )
4789 return None
GlennRC050596c2015-11-18 17:06:41 -08004790 except TypeError:
4791 main.log.exception( self.name + ": Object not as expected" )
4792 return None
4793 except pexpect.EOF:
4794 main.log.error( self.name + ": EOF exception found" )
4795 main.log.error( self.name + ": " + self.handle.before )
4796 main.cleanup()
4797 main.exit()
4798 except Exception:
4799 main.log.exception( self.name + ": Uncaught exception!" )
4800 main.cleanup()
4801 main.exit()
4802
4803 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4804 """
4805 Descrition: sets the controller(s) for the specified device
4806
4807 Parameters:
4808 Required: uri - String: The uri of the device(switch).
4809 ip - String or List: The ip address of the controller.
4810 This parameter can be formed in a couple of different ways.
4811 VALID:
4812 10.0.0.1 - just the ip address
4813 tcp:10.0.0.1 - the protocol and the ip address
4814 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4815 so that you can add controllers with different
4816 protocols and ports
4817 INVALID:
4818 10.0.0.1:6653 - this is not supported by ONOS
4819
4820 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4821 port - The port number.
4822 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4823
4824 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4825 """
4826 try:
4827 cmd = "device-setcontrollers"
4828
4829 if jsonFormat:
4830 cmd += " -j"
4831 cmd += " " + uri
4832 if isinstance( ip, str ):
4833 ip = [ip]
4834 for item in ip:
4835 if ":" in item:
4836 sitem = item.split( ":" )
4837 if len(sitem) == 3:
4838 cmd += " " + item
4839 elif "." in sitem[1]:
4840 cmd += " {}:{}".format(item, port)
4841 else:
4842 main.log.error( "Malformed entry: " + item )
4843 raise TypeError
4844 else:
4845 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004846 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004847 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004848 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004849 if "Error" in response:
4850 main.log.error( response )
4851 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004852 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004853 except AssertionError:
4854 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004855 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004856 except TypeError:
4857 main.log.exception( self.name + ": Object not as expected" )
4858 return main.FALSE
4859 except pexpect.EOF:
4860 main.log.error( self.name + ": EOF exception found" )
4861 main.log.error( self.name + ": " + self.handle.before )
4862 main.cleanup()
4863 main.exit()
4864 except Exception:
4865 main.log.exception( self.name + ": Uncaught exception!" )
4866 main.cleanup()
4867 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004868
4869 def removeDevice( self, device ):
4870 '''
4871 Description:
4872 Remove a device from ONOS by passing the uri of the device(s).
4873 Parameters:
4874 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4875 Returns:
4876 Returns main.FALSE if an exception is thrown or an error is present
4877 in the response. Otherwise, returns main.TRUE.
4878 NOTE:
4879 If a host cannot be removed, then this function will return main.FALSE
4880 '''
4881 try:
4882 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004883 deviceStr = device
4884 device = []
4885 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004886
4887 for d in device:
4888 time.sleep( 1 )
4889 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004890 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004891 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004892 if "Error" in response:
4893 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4894 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004895 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004896 except AssertionError:
4897 main.log.exception( "" )
4898 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004899 except TypeError:
4900 main.log.exception( self.name + ": Object not as expected" )
4901 return main.FALSE
4902 except pexpect.EOF:
4903 main.log.error( self.name + ": EOF exception found" )
4904 main.log.error( self.name + ": " + self.handle.before )
4905 main.cleanup()
4906 main.exit()
4907 except Exception:
4908 main.log.exception( self.name + ": Uncaught exception!" )
4909 main.cleanup()
4910 main.exit()
4911
4912 def removeHost( self, host ):
4913 '''
4914 Description:
4915 Remove a host from ONOS by passing the id of the host(s)
4916 Parameters:
4917 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4918 Returns:
4919 Returns main.FALSE if an exception is thrown or an error is present
4920 in the response. Otherwise, returns main.TRUE.
4921 NOTE:
4922 If a host cannot be removed, then this function will return main.FALSE
4923 '''
4924 try:
4925 if type( host ) is str:
4926 host = list( host )
4927
4928 for h in host:
4929 time.sleep( 1 )
4930 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004931 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004932 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004933 if "Error" in response:
4934 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4935 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004936 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004937 except AssertionError:
4938 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004939 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004940 except TypeError:
4941 main.log.exception( self.name + ": Object not as expected" )
4942 return main.FALSE
4943 except pexpect.EOF:
4944 main.log.error( self.name + ": EOF exception found" )
4945 main.log.error( self.name + ": " + self.handle.before )
4946 main.cleanup()
4947 main.exit()
4948 except Exception:
4949 main.log.exception( self.name + ": Uncaught exception!" )
4950 main.cleanup()
4951 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004952
YPZhangfebf7302016-05-24 16:45:56 -07004953 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004954 '''
4955 Description:
4956 Bring link down or up in the null-provider.
4957 params:
4958 begin - (string) One end of a device or switch.
4959 end - (string) the other end of the device or switch
4960 returns:
4961 main.TRUE if no exceptions were thrown and no Errors are
4962 present in the resoponse. Otherwise, returns main.FALSE
4963 '''
4964 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004965 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004966 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004967 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004968 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004969 if "Error" in response or "Failure" in response:
4970 main.log.error( response )
4971 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004972 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004973 except AssertionError:
4974 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004975 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004976 except TypeError:
4977 main.log.exception( self.name + ": Object not as expected" )
4978 return main.FALSE
4979 except pexpect.EOF:
4980 main.log.error( self.name + ": EOF exception found" )
4981 main.log.error( self.name + ": " + self.handle.before )
4982 main.cleanup()
4983 main.exit()
4984 except Exception:
4985 main.log.exception( self.name + ": Uncaught exception!" )
4986 main.cleanup()
4987 main.exit()
4988
Jon Hall2c8959e2016-12-16 12:17:34 -08004989 def portstate( self, dpid, port, state ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07004990 '''
4991 Description:
4992 Changes the state of port in an OF switch by means of the
4993 PORTSTATUS OF messages.
4994 params:
Jon Hall2c8959e2016-12-16 12:17:34 -08004995 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
4996 port - (string) target port in the device. Ex: '2'
4997 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07004998 returns:
4999 main.TRUE if no exceptions were thrown and no Errors are
5000 present in the resoponse. Otherwise, returns main.FALSE
5001 '''
5002 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005003 state = state.lower()
5004 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005005 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005006 response = self.sendline( cmd, showResponse=True )
5007 assert response is not None, "Error in sendline"
5008 assert "Command not found:" not in response, response
5009 if "Error" in response or "Failure" in response:
5010 main.log.error( response )
5011 return main.FALSE
5012 return main.TRUE
5013 except AssertionError:
5014 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005015 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005016 except TypeError:
5017 main.log.exception( self.name + ": Object not as expected" )
5018 return main.FALSE
5019 except pexpect.EOF:
5020 main.log.error( self.name + ": EOF exception found" )
5021 main.log.error( self.name + ": " + self.handle.before )
5022 main.cleanup()
5023 main.exit()
5024 except Exception:
5025 main.log.exception( self.name + ": Uncaught exception!" )
5026 main.cleanup()
5027 main.exit()
5028
5029 def logSet( self, level="INFO", app="org.onosproject" ):
5030 """
5031 Set the logging level to lvl for a specific app
5032 returns main.TRUE on success
5033 returns main.FALSE if Error occurred
5034 if noExit is True, TestON will not exit, but clean up
5035 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5036 Level defaults to INFO
5037 """
5038 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005039 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005040 self.handle.expect( "onos>" )
5041
5042 response = self.handle.before
5043 if re.search( "Error", response ):
5044 return main.FALSE
5045 return main.TRUE
5046 except pexpect.TIMEOUT:
5047 main.log.exception( self.name + ": TIMEOUT exception found" )
5048 main.cleanup()
5049 main.exit()
5050 except pexpect.EOF:
5051 main.log.error( self.name + ": EOF exception found" )
5052 main.log.error( self.name + ": " + self.handle.before )
5053 main.cleanup()
5054 main.exit()
5055 except Exception:
5056 main.log.exception( self.name + ": Uncaught exception!" )
5057 main.cleanup()
5058 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005059
5060 def getGraphDict( self, timeout=60, includeHost=False ):
5061 """
5062 Return a dictionary which describes the latest network topology data as a
5063 graph.
5064 An example of the dictionary:
5065 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5066 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5067 Each vertex should at least have an 'edges' attribute which describes the
5068 adjacency information. The value of 'edges' attribute is also represented by
5069 a dictionary, which maps each edge (identified by the neighbor vertex) to a
5070 list of attributes.
5071 An example of the edges dictionary:
5072 'edges': { vertex2: { 'port': ..., 'weight': ... },
5073 vertex3: { 'port': ..., 'weight': ... } }
5074 If includeHost == True, all hosts (and host-switch links) will be included
5075 in topology data.
5076 """
5077 graphDict = {}
5078 try:
5079 links = self.links()
5080 links = json.loads( links )
5081 devices = self.devices()
5082 devices = json.loads( devices )
5083 idToDevice = {}
5084 for device in devices:
5085 idToDevice[ device[ 'id' ] ] = device
5086 if includeHost:
5087 hosts = self.hosts()
5088 # FIXME: support 'includeHost' argument
5089 for link in links:
5090 nodeA = link[ 'src' ][ 'device' ]
5091 nodeB = link[ 'dst' ][ 'device' ]
5092 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005093 if nodeA not in graphDict.keys():
5094 graphDict[ nodeA ] = { 'edges': {},
5095 'dpid': idToDevice[ nodeA ][ 'id' ][3:],
5096 'type': idToDevice[ nodeA ][ 'type' ],
5097 'available': idToDevice[ nodeA ][ 'available' ],
5098 'role': idToDevice[ nodeA ][ 'role' ],
5099 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5100 'hw': idToDevice[ nodeA ][ 'hw' ],
5101 'sw': idToDevice[ nodeA ][ 'sw' ],
5102 'serial': idToDevice[ nodeA ][ 'serial' ],
5103 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
5104 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005105 else:
5106 # Assert nodeB is not connected to any current links of nodeA
5107 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005108 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5109 'type': link[ 'type' ],
5110 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005111 return graphDict
5112 except ( TypeError, ValueError ):
5113 main.log.exception( self.name + ": Object not as expected" )
5114 return None
5115 except KeyError:
5116 main.log.exception( self.name + ": KeyError exception found" )
5117 return None
5118 except AssertionError:
5119 main.log.exception( self.name + ": AssertionError exception found" )
5120 return None
5121 except pexpect.EOF:
5122 main.log.error( self.name + ": EOF exception found" )
5123 main.log.error( self.name + ": " + self.handle.before )
5124 return None
5125 except Exception:
5126 main.log.exception( self.name + ": Uncaught exception!" )
5127 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005128
5129 def getIntentPerfSummary( self ):
5130 '''
5131 Send command to check intent-perf summary
5132 Returns: dictionary for intent-perf summary
5133 if something wrong, function will return None
5134 '''
5135 cmd = "intent-perf -s"
5136 respDic = {}
5137 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005138 assert resp is not None, "Error in sendline"
5139 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005140 try:
5141 # Generate the dictionary to return
5142 for l in resp.split( "\n" ):
5143 # Delete any white space in line
5144 temp = re.sub( r'\s+', '', l )
5145 temp = temp.split( ":" )
5146 respDic[ temp[0] ] = temp[ 1 ]
5147
5148 except (TypeError, ValueError):
5149 main.log.exception( self.name + ": Object not as expected" )
5150 return None
5151 except KeyError:
5152 main.log.exception( self.name + ": KeyError exception found" )
5153 return None
5154 except AssertionError:
5155 main.log.exception( self.name + ": AssertionError exception found" )
5156 return None
5157 except pexpect.EOF:
5158 main.log.error( self.name + ": EOF exception found" )
5159 main.log.error( self.name + ": " + self.handle.before )
5160 return None
5161 except Exception:
5162 main.log.exception( self.name + ": Uncaught exception!" )
5163 return None
5164 return respDic
5165
Chiyu Chengec63bde2016-11-17 18:11:36 -08005166 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005167 """
5168 Searches the latest ONOS log file for the given search term and
5169 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005170
chengchiyu08303a02016-09-08 17:40:26 -07005171 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005172 searchTerm:
5173 The string to grep from the ONOS log.
5174 startLine:
5175 The term that decides which line is the start to search the searchTerm in
5176 the karaf log. For now, startTerm only works in 'first' mode.
5177 logNum:
5178 In some extreme cases, one karaf log is not big enough to contain all the
5179 information.Because of this, search mutiply logs is necessary to capture
5180 the right result. logNum is the number of karaf logs that we need to search
5181 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005182 mode:
5183 all: return all the strings that contain the search term
5184 last: return the last string that contains the search term
5185 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005186 num: return the number of times that the searchTerm appears in the log
5187 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005188 """
5189 try:
5190 assert type( searchTerm ) is str
Jon Halle0f0b342017-04-18 11:43:47 -07005191 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005192 logPath = '/opt/onos/log/karaf.log.'
5193 logPaths = '/opt/onos/log/karaf.log'
5194 for i in range( 1, logNum ):
5195 logPaths = logPath + str( i ) + " " + logPaths
5196 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005197 if startLine:
5198 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5199 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005200 if mode == 'all':
5201 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005202 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005203 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005204 elif mode == 'first':
5205 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5206 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005207 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005208 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005209 return num
You Wang6d301d42017-04-21 10:49:33 -07005210 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005211 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
5212 return int(totalLines)
You Wang6d301d42017-04-21 10:49:33 -07005213 else:
5214 main.log.error( self.name + " unsupported mode" )
5215 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005216 before = self.sendline( cmd )
5217 before = before.splitlines()
5218 # make sure the returned list only contains the search term
5219 returnLines = [line for line in before if searchTerm in line]
5220 return returnLines
5221 except AssertionError:
5222 main.log.error( self.name + " searchTerm is not string type" )
5223 return None
5224 except pexpect.EOF:
5225 main.log.error( self.name + ": EOF exception found" )
5226 main.log.error( self.name + ": " + self.handle.before )
5227 main.cleanup()
5228 main.exit()
5229 except pexpect.TIMEOUT:
5230 main.log.error( self.name + ": TIMEOUT exception found" )
5231 main.log.error( self.name + ": " + self.handle.before )
5232 main.cleanup()
5233 main.exit()
5234 except Exception:
5235 main.log.exception( self.name + ": Uncaught exception!" )
5236 main.cleanup()
5237 main.exit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005238
5239 def vplsShow( self, jsonFormat=True ):
5240 """
5241 Description: Returns result of onos:vpls show, which should list the
5242 configured VPLS networks and the assigned interfaces.
5243 Optional:
5244 * jsonFormat: enable json formatting of output
5245 Returns:
5246 The output of the command or None on error.
5247 """
5248 try:
5249 cmdStr = "vpls show"
5250 if jsonFormat:
5251 raise NotImplementedError
5252 cmdStr += " -j"
5253 handle = self.sendline( cmdStr )
5254 assert handle is not None, "Error in sendline"
5255 assert "Command not found:" not in handle, handle
5256 return handle
5257 except AssertionError:
5258 main.log.exception( "" )
5259 return None
5260 except TypeError:
5261 main.log.exception( self.name + ": Object not as expected" )
5262 return None
5263 except pexpect.EOF:
5264 main.log.error( self.name + ": EOF exception found" )
5265 main.log.error( self.name + ": " + self.handle.before )
5266 main.cleanup()
5267 main.exit()
5268 except NotImplementedError:
5269 main.log.exception( self.name + ": Json output not supported")
5270 return None
5271 except Exception:
5272 main.log.exception( self.name + ": Uncaught exception!" )
5273 main.cleanup()
5274 main.exit()
5275
5276 def parseVplsShow( self ):
5277 """
5278 Parse the cli output of 'vpls show' into json output. This is required
5279 as there is currently no json output available.
5280 """
5281 try:
5282 output = []
5283 raw = self.vplsShow( jsonFormat=False )
5284 namePat = "VPLS name: (?P<name>\w+)"
5285 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5286 encapPat = "Encapsulation: (?P<encap>\w+)"
5287 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5288 mIter = re.finditer( pattern, raw )
5289 for match in mIter:
5290 item = {}
5291 item[ 'name' ] = match.group( 'name' )
5292 ifaces = match.group( 'interfaces' ).split( ', ')
5293 if ifaces == [ "" ]:
5294 ifaces = []
5295 item[ 'interfaces' ] = ifaces
5296 encap = match.group( 'encap' )
5297 if encap != 'NONE':
5298 item[ 'encapsulation' ] = encap.lower()
5299 output.append( item )
5300 return output
5301 except Exception:
5302 main.log.exception( self.name + ": Uncaught exception!" )
5303 main.cleanup()
5304 main.exit()
5305
5306 def vplsList( self, jsonFormat=True ):
5307 """
5308 Description: Returns result of onos:vpls list, which should list the
5309 configured VPLS networks.
5310 Optional:
5311 * jsonFormat: enable json formatting of output
5312 """
5313 try:
5314 cmdStr = "vpls list"
5315 if jsonFormat:
5316 raise NotImplementedError
5317 cmdStr += " -j"
5318 handle = self.sendline( cmdStr )
5319 assert handle is not None, "Error in sendline"
5320 assert "Command not found:" not in handle, handle
5321 return handle
5322 except AssertionError:
5323 main.log.exception( "" )
5324 return None
5325 except TypeError:
5326 main.log.exception( self.name + ": Object not as expected" )
5327 return None
5328 except pexpect.EOF:
5329 main.log.error( self.name + ": EOF exception found" )
5330 main.log.error( self.name + ": " + self.handle.before )
5331 main.cleanup()
5332 main.exit()
5333 except NotImplementedError:
5334 main.log.exception( self.name + ": Json output not supported")
5335 return None
5336 except Exception:
5337 main.log.exception( self.name + ": Uncaught exception!" )
5338 main.cleanup()
5339 main.exit()
5340
5341 def vplsCreate( self, network ):
5342 """
5343 CLI command to create a new VPLS network.
5344 Required arguments:
5345 network - String name of the network to create.
5346 returns:
5347 main.TRUE on success and main.FALSE on failure
5348 """
5349 try:
5350 network = str( network )
5351 cmdStr = "vpls create "
5352 cmdStr += network
5353 output = self.sendline( cmdStr )
5354 assert output is not None, "Error in sendline"
5355 assert "Command not found:" not in output, output
5356 assert "Error executing command" not in output, output
5357 assert "VPLS already exists:" not in output, output
5358 return main.TRUE
5359 except AssertionError:
5360 main.log.exception( "" )
5361 return main.FALSE
5362 except TypeError:
5363 main.log.exception( self.name + ": Object not as expected" )
5364 return main.FALSE
5365 except pexpect.EOF:
5366 main.log.error( self.name + ": EOF exception found" )
5367 main.log.error( self.name + ": " + self.handle.before )
5368 main.cleanup()
5369 main.exit()
5370 except Exception:
5371 main.log.exception( self.name + ": Uncaught exception!" )
5372 main.cleanup()
5373 main.exit()
5374
5375 def vplsDelete( self, network ):
5376 """
5377 CLI command to delete a VPLS network.
5378 Required arguments:
5379 network - Name of the network to delete.
5380 returns:
5381 main.TRUE on success and main.FALSE on failure
5382 """
5383 try:
5384 network = str( network )
5385 cmdStr = "vpls delete "
5386 cmdStr += network
5387 output = self.sendline( cmdStr )
5388 assert output is not None, "Error in sendline"
5389 assert "Command not found:" not in output, output
5390 assert "Error executing command" not in output, output
5391 assert " not found" not in output, output
5392 return main.TRUE
5393 except AssertionError:
5394 main.log.exception( "" )
5395 return main.FALSE
5396 except TypeError:
5397 main.log.exception( self.name + ": Object not as expected" )
5398 return main.FALSE
5399 except pexpect.EOF:
5400 main.log.error( self.name + ": EOF exception found" )
5401 main.log.error( self.name + ": " + self.handle.before )
5402 main.cleanup()
5403 main.exit()
5404 except Exception:
5405 main.log.exception( self.name + ": Uncaught exception!" )
5406 main.cleanup()
5407 main.exit()
5408
5409 def vplsAddIface( self, network, iface ):
5410 """
5411 CLI command to add an interface to a VPLS network.
5412 Required arguments:
5413 network - Name of the network to add the interface to.
5414 iface - The ONOS name for an interface.
5415 returns:
5416 main.TRUE on success and main.FALSE on failure
5417 """
5418 try:
5419 network = str( network )
5420 iface = str( iface )
5421 cmdStr = "vpls add-if "
5422 cmdStr += network + " " + iface
5423 output = self.sendline( cmdStr )
5424 assert output is not None, "Error in sendline"
5425 assert "Command not found:" not in output, output
5426 assert "Error executing command" not in output, output
5427 assert "already associated to network" not in output, output
5428 assert "Interface cannot be added." not in output, output
5429 return main.TRUE
5430 except AssertionError:
5431 main.log.exception( "" )
5432 return main.FALSE
5433 except TypeError:
5434 main.log.exception( self.name + ": Object not as expected" )
5435 return main.FALSE
5436 except pexpect.EOF:
5437 main.log.error( self.name + ": EOF exception found" )
5438 main.log.error( self.name + ": " + self.handle.before )
5439 main.cleanup()
5440 main.exit()
5441 except Exception:
5442 main.log.exception( self.name + ": Uncaught exception!" )
5443 main.cleanup()
5444 main.exit()
5445
5446 def vplsRemIface( self, network, iface ):
5447 """
5448 CLI command to remove an interface from a VPLS network.
5449 Required arguments:
5450 network - Name of the network to remove the interface from.
5451 iface - Name of the interface to remove.
5452 returns:
5453 main.TRUE on success and main.FALSE on failure
5454 """
5455 try:
5456 iface = str( iface )
5457 cmdStr = "vpls rem-if "
5458 cmdStr += network + " " + iface
5459 output = self.sendline( cmdStr )
5460 assert output is not None, "Error in sendline"
5461 assert "Command not found:" not in output, output
5462 assert "Error executing command" not in output, output
5463 assert "is not configured" not in output, output
5464 return main.TRUE
5465 except AssertionError:
5466 main.log.exception( "" )
5467 return main.FALSE
5468 except TypeError:
5469 main.log.exception( self.name + ": Object not as expected" )
5470 return main.FALSE
5471 except pexpect.EOF:
5472 main.log.error( self.name + ": EOF exception found" )
5473 main.log.error( self.name + ": " + self.handle.before )
5474 main.cleanup()
5475 main.exit()
5476 except Exception:
5477 main.log.exception( self.name + ": Uncaught exception!" )
5478 main.cleanup()
5479 main.exit()
5480
5481 def vplsClean( self ):
5482 """
5483 Description: Clears the VPLS app configuration.
5484 Returns: main.TRUE on success and main.FALSE on failure
5485 """
5486 try:
5487 cmdStr = "vpls clean"
5488 handle = self.sendline( cmdStr )
5489 assert handle is not None, "Error in sendline"
5490 assert "Command not found:" not in handle, handle
5491 return handle
5492 except AssertionError:
5493 main.log.exception( "" )
5494 return main.FALSE
5495 except TypeError:
5496 main.log.exception( self.name + ": Object not as expected" )
5497 return main.FALSE
5498 except pexpect.EOF:
5499 main.log.error( self.name + ": EOF exception found" )
5500 main.log.error( self.name + ": " + self.handle.before )
5501 main.cleanup()
5502 main.exit()
5503 except Exception:
5504 main.log.exception( self.name + ": Uncaught exception!" )
5505 main.cleanup()
5506 main.exit()
5507
5508 def vplsSetEncap( self, network, encapType ):
5509 """
5510 CLI command to add an interface to a VPLS network.
5511 Required arguments:
5512 network - Name of the network to create.
5513 encapType - Type of encapsulation.
5514 returns:
5515 main.TRUE on success and main.FALSE on failure
5516 """
5517 try:
5518 network = str( network )
5519 encapType = str( encapType ).upper()
5520 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5521 cmdStr = "vpls set-encap "
5522 cmdStr += network + " " + encapType
5523 output = self.sendline( cmdStr )
5524 assert output is not None, "Error in sendline"
5525 assert "Command not found:" not in output, output
5526 assert "Error executing command" not in output, output
5527 assert "already associated to network" not in output, output
5528 assert "Encapsulation type " not in output, output
5529 return main.TRUE
5530 except AssertionError:
5531 main.log.exception( "" )
5532 return main.FALSE
5533 except TypeError:
5534 main.log.exception( self.name + ": Object not as expected" )
5535 return main.FALSE
5536 except pexpect.EOF:
5537 main.log.error( self.name + ": EOF exception found" )
5538 main.log.error( self.name + ": " + self.handle.before )
5539 main.cleanup()
5540 main.exit()
5541 except Exception:
5542 main.log.exception( self.name + ": Uncaught exception!" )
5543 main.cleanup()
5544 main.exit()
5545
5546 def interfaces( self, jsonFormat=True ):
5547 """
5548 Description: Returns result of interfaces command.
5549 Optional:
5550 * jsonFormat: enable json formatting of output
5551 Returns:
5552 The output of the command or None on error.
5553 """
5554 try:
5555 cmdStr = "interfaces"
5556 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005557 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005558 cmdStr += " -j"
5559 handle = self.sendline( cmdStr )
5560 assert handle is not None, "Error in sendline"
5561 assert "Command not found:" not in handle, handle
5562 return handle
5563 except AssertionError:
5564 main.log.exception( "" )
5565 return None
5566 except TypeError:
5567 main.log.exception( self.name + ": Object not as expected" )
5568 return None
5569 except pexpect.EOF:
5570 main.log.error( self.name + ": EOF exception found" )
5571 main.log.error( self.name + ": " + self.handle.before )
5572 main.cleanup()
5573 main.exit()
5574 except NotImplementedError:
5575 main.log.exception( self.name + ": Json output not supported")
5576 return None
5577 except Exception:
5578 main.log.exception( self.name + ": Uncaught exception!" )
5579 main.cleanup()
5580 main.exit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005581
5582 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
5583 '''
5584 Get the timestamp of searchTerm from karaf log.
5585
5586 Arguments:
5587 splitTerm_before and splitTerm_after:
5588
5589 The terms that split the string that contains the timeStamp of
5590 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5591 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5592 and the splitTerm_after is "x"
5593
5594 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005595 Please look at the "logsearch" Function in onosclidriver.py
Chiyu Chengec63bde2016-11-17 18:11:36 -08005596 '''
5597 if logNum < 0:
5598 main.log.error("Get wrong log number ")
5599 return main.ERROR
5600 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
5601 if len(lines) == 0:
5602 main.log.warn( "Captured timestamp string is empty" )
5603 return main.ERROR
5604 lines = lines[ 0 ]
5605 try:
5606 assert type(lines) is str
5607 # get the target value
5608 line = lines.split( splitTerm_before )
5609 key = line[ 1 ].split( splitTerm_after )
5610 return int( key[ 0 ] )
5611 except IndexError:
5612 main.log.warn( "Index Error!" )
5613 return main.ERROR
5614 except AssertionError:
5615 main.log.warn( "Search Term Not Found " )
5616 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005617
5618 def workQueueAdd( self, queueName, value ):
5619 """
5620 CLI command to add a string to the specified Work Queue.
5621 This function uses the distributed primitives test app, which
5622 gives some cli access to distributed primitives for testing
5623 purposes only.
5624
5625 Required arguments:
5626 queueName - The name of the queue to add to
5627 value - The value to add to the queue
5628 returns:
5629 main.TRUE on success, main.FALSE on failure and
5630 main.ERROR on error.
5631 """
5632 try:
5633 queueName = str( queueName )
5634 value = str( value )
5635 prefix = "work-queue-test"
5636 operation = "add"
5637 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5638 output = self.distPrimitivesSend( cmdStr )
5639 if "Invalid operation name" in output:
5640 main.log.warn( output )
5641 return main.ERROR
5642 elif "Done" in output:
5643 return main.TRUE
5644 except TypeError:
5645 main.log.exception( self.name + ": Object not as expected" )
5646 return main.ERROR
5647 except Exception:
5648 main.log.exception( self.name + ": Uncaught exception!" )
5649 main.cleanup()
5650 main.exit()
5651
5652 def workQueueAddMultiple( self, queueName, value1, value2 ):
5653 """
5654 CLI command to add two strings to the specified Work Queue.
5655 This function uses the distributed primitives test app, which
5656 gives some cli access to distributed primitives for testing
5657 purposes only.
5658
5659 Required arguments:
5660 queueName - The name of the queue to add to
5661 value1 - The first value to add to the queue
5662 value2 - The second value to add to the queue
5663 returns:
5664 main.TRUE on success, main.FALSE on failure and
5665 main.ERROR on error.
5666 """
5667 try:
5668 queueName = str( queueName )
5669 value1 = str( value1 )
5670 value2 = str( value2 )
5671 prefix = "work-queue-test"
5672 operation = "addMultiple"
5673 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5674 output = self.distPrimitivesSend( cmdStr )
5675 if "Invalid operation name" in output:
5676 main.log.warn( output )
5677 return main.ERROR
5678 elif "Done" in output:
5679 return main.TRUE
5680 except TypeError:
5681 main.log.exception( self.name + ": Object not as expected" )
5682 return main.ERROR
5683 except Exception:
5684 main.log.exception( self.name + ": Uncaught exception!" )
5685 main.cleanup()
5686 main.exit()
5687
5688 def workQueueTakeAndComplete( self, queueName, number=1 ):
5689 """
5690 CLI command to take a value from the specified Work Queue and compelte it.
5691 This function uses the distributed primitives test app, which
5692 gives some cli access to distributed primitives for testing
5693 purposes only.
5694
5695 Required arguments:
5696 queueName - The name of the queue to add to
5697 number - The number of items to take and complete
5698 returns:
5699 main.TRUE on success, main.FALSE on failure and
5700 main.ERROR on error.
5701 """
5702 try:
5703 queueName = str( queueName )
5704 number = str( int( number ) )
5705 prefix = "work-queue-test"
5706 operation = "takeAndComplete"
5707 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5708 output = self.distPrimitivesSend( cmdStr )
5709 if "Invalid operation name" in output:
5710 main.log.warn( output )
5711 return main.ERROR
5712 elif "Done" in output:
5713 return main.TRUE
5714 except TypeError:
5715 main.log.exception( self.name + ": Object not as expected" )
5716 return main.ERROR
5717 except Exception:
5718 main.log.exception( self.name + ": Uncaught exception!" )
5719 main.cleanup()
5720 main.exit()
5721
5722 def workQueueDestroy( self, queueName ):
5723 """
5724 CLI command to destroy the specified Work Queue.
5725 This function uses the distributed primitives test app, which
5726 gives some cli access to distributed primitives for testing
5727 purposes only.
5728
5729 Required arguments:
5730 queueName - The name of the queue to add to
5731 returns:
5732 main.TRUE on success, main.FALSE on failure and
5733 main.ERROR on error.
5734 """
5735 try:
5736 queueName = str( queueName )
5737 prefix = "work-queue-test"
5738 operation = "destroy"
5739 cmdStr = " ".join( [ prefix, queueName, operation ] )
5740 output = self.distPrimitivesSend( cmdStr )
5741 if "Invalid operation name" in output:
5742 main.log.warn( output )
5743 return main.ERROR
5744 return main.TRUE
5745 except TypeError:
5746 main.log.exception( self.name + ": Object not as expected" )
5747 return main.ERROR
5748 except Exception:
5749 main.log.exception( self.name + ": Uncaught exception!" )
5750 main.cleanup()
5751 main.exit()
5752
5753 def workQueueTotalPending( self, queueName ):
5754 """
5755 CLI command to get the Total Pending items of the specified Work Queue.
5756 This function uses the distributed primitives test app, which
5757 gives some cli access to distributed primitives for testing
5758 purposes only.
5759
5760 Required arguments:
5761 queueName - The name of the queue to add to
5762 returns:
5763 The number of Pending items in the specified work queue or
5764 None on error
5765 """
5766 try:
5767 queueName = str( queueName )
5768 prefix = "work-queue-test"
5769 operation = "totalPending"
5770 cmdStr = " ".join( [ prefix, queueName, operation ] )
5771 output = self.distPrimitivesSend( cmdStr )
5772 pattern = r'\d+'
5773 if "Invalid operation name" in output:
5774 main.log.warn( output )
5775 return None
5776 else:
5777 match = re.search( pattern, output )
5778 return match.group(0)
5779 except ( AttributeError, TypeError ):
5780 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5781 return None
5782 except Exception:
5783 main.log.exception( self.name + ": Uncaught exception!" )
5784 main.cleanup()
5785 main.exit()
5786
5787 def workQueueTotalCompleted( self, queueName ):
5788 """
5789 CLI command to get the Total Completed items of the specified Work Queue.
5790 This function uses the distributed primitives test app, which
5791 gives some cli access to distributed primitives for testing
5792 purposes only.
5793
5794 Required arguments:
5795 queueName - The name of the queue to add to
5796 returns:
5797 The number of complete items in the specified work queue or
5798 None on error
5799 """
5800 try:
5801 queueName = str( queueName )
5802 prefix = "work-queue-test"
5803 operation = "totalCompleted"
5804 cmdStr = " ".join( [ prefix, queueName, operation ] )
5805 output = self.distPrimitivesSend( cmdStr )
5806 pattern = r'\d+'
5807 if "Invalid operation name" in output:
5808 main.log.warn( output )
5809 return None
5810 else:
5811 match = re.search( pattern, output )
5812 return match.group(0)
5813 except ( AttributeError, TypeError ):
5814 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5815 return None
5816 except Exception:
5817 main.log.exception( self.name + ": Uncaught exception!" )
5818 main.cleanup()
5819 main.exit()
5820
5821 def workQueueTotalInProgress( self, queueName ):
5822 """
5823 CLI command to get the Total In Progress items of the specified Work Queue.
5824 This function uses the distributed primitives test app, which
5825 gives some cli access to distributed primitives for testing
5826 purposes only.
5827
5828 Required arguments:
5829 queueName - The name of the queue to add to
5830 returns:
5831 The number of In Progress items in the specified work queue or
5832 None on error
5833 """
5834 try:
5835 queueName = str( queueName )
5836 prefix = "work-queue-test"
5837 operation = "totalInProgress"
5838 cmdStr = " ".join( [ prefix, queueName, operation ] )
5839 output = self.distPrimitivesSend( cmdStr )
5840 pattern = r'\d+'
5841 if "Invalid operation name" in output:
5842 main.log.warn( output )
5843 return None
5844 else:
5845 match = re.search( pattern, output )
5846 return match.group(0)
5847 except ( AttributeError, TypeError ):
5848 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5849 return None
5850 except Exception:
5851 main.log.exception( self.name + ": Uncaught exception!" )
5852 main.cleanup()
5853 main.exit()