blob: b208b3cb072cdc07e0fdfde22ae49ae425978a56 [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 ) +
2177 " on 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 Hallc6793552016-01-19 14:18:37 -08002183 for intents in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002184 if intentsId[ i ] == intents[ 'id' ]:
2185 stateDict[ 'state' ] = intents[ 'state' ]
2186 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 ):
2190 main.log.info( "Cannot find some of the intent ID state" )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002191 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002192 else:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002193 main.log.info( "Invalid intents ID entry" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002194 return None
Jon Hallc6793552016-01-19 14:18:37 -08002195 except ( TypeError, ValueError ):
2196 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002197 return None
2198 except pexpect.EOF:
2199 main.log.error( self.name + ": EOF exception found" )
2200 main.log.error( self.name + ": " + self.handle.before )
2201 main.cleanup()
2202 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002203 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002204 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002205 main.cleanup()
2206 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002207
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002208 def checkIntentState( self, intentsId, bandwidthFlag=False, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002209 """
2210 Description:
2211 Check intents state
2212 Required:
2213 intentsId - List of intents ID to be checked
2214 Optional:
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002215 bandwidthFlag - Check the bandwidth allocations. If bandwidth is
2216 specified, then check for bandwidth allocations
kelvin-onlabf512e942015-06-08 19:42:59 -07002217 expectedState - Check the expected state(s) of each intents
2218 state in the list.
2219 *NOTE: You can pass in a list of expected state,
2220 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002221 Return:
kelvin-onlabf512e942015-06-08 19:42:59 -07002222 Returns main.TRUE only if all intent are the same as expected states
2223 , otherwise, returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002224 """
2225 try:
2226 # Generating a dictionary: intent id as a key and state as value
kelvin-onlabf512e942015-06-08 19:42:59 -07002227 returnValue = main.TRUE
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002228 intentsDict = self.getIntentState( intentsId )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002229 if len( intentsId ) != len( intentsDict ):
Jon Hallae04e622016-01-27 10:38:05 -08002230 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002231 "getting intents state" )
2232 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002233
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002234 failFlag = False
2235 if bandwidthFlag:
2236 rawAlloc = self.allocations()
2237 expectedFormat = open( os.path.dirname( main.testFile ) + main.params[ 'DEPENDENCY' ][ 'filePath' ], 'r' )
2238 ONOSOutput = StringIO(rawAlloc)
2239
2240 for actual,expected in izip(ONOSOutput,expectedFormat):
2241 actual = actual.rstrip()
2242 expected = expected.rstrip()
2243 if actual != expected and 'allocated' in actual and 'allocated' in expected:
2244 marker1 = actual.find('allocated')
2245 m1 = actual[:marker1]
2246 marker2 = expected.find('allocated')
2247 m2 = expected[:marker2]
2248 if m1 != m2:
2249 failFlag = True
2250 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2251 failFlag = True
2252
2253 expectedFormat.close()
2254 ONOSOutput.close()
2255 bandwidthFlag = False
2256
2257 if failFlag:
2258 main.log.error("Bandwidth not allocated correctly using Intents!!")
2259 returnValue = main.FALSE
2260 return returnValue
2261
kelvin-onlabf512e942015-06-08 19:42:59 -07002262 if isinstance( expectedState, types.StringType ):
2263 for intents in intentsDict:
2264 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002265 main.log.debug( self.name + " : Intent ID - " +
2266 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002267 " actual state = " +
2268 intents.get( 'state' )
2269 + " does not equal expected state = "
2270 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002271 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002272
2273 elif isinstance( expectedState, types.ListType ):
2274 for intents in intentsDict:
2275 if not any( state == intents.get( 'state' ) for state in
2276 expectedState ):
2277 main.log.debug( self.name + " : Intent ID - " +
2278 intents.get( 'id' ) +
2279 " actual state = " +
2280 intents.get( 'state' ) +
2281 " does not equal expected states = "
2282 + str( expectedState ) )
2283 returnValue = main.FALSE
2284
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002285 if returnValue == main.TRUE:
2286 main.log.info( self.name + ": All " +
2287 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002288 " intents are in " + str( expectedState ) +
2289 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002290 return returnValue
2291 except TypeError:
2292 main.log.exception( self.name + ": Object not as expected" )
2293 return None
2294 except pexpect.EOF:
2295 main.log.error( self.name + ": EOF exception found" )
2296 main.log.error( self.name + ": " + self.handle.before )
2297 main.cleanup()
2298 main.exit()
2299 except Exception:
2300 main.log.exception( self.name + ": Uncaught exception!" )
2301 main.cleanup()
2302 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002303
You Wang66518af2016-05-16 15:32:59 -07002304 def compareIntent( self, intentDict ):
2305 """
2306 Description:
2307 Compare the intent ids and states provided in the argument with all intents in ONOS
2308 Return:
2309 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2310 Arguments:
2311 intentDict: a dictionary which maps intent ids to intent states
2312 """
2313 try:
2314 intentsRaw = self.intents()
2315 intentsJson = json.loads( intentsRaw )
2316 intentDictONOS = {}
2317 for intent in intentsJson:
2318 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002319 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002320 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002321 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002322 str( len( intentDict ) ) + " expected and " +
2323 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002324 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002325 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002326 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002327 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2328 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002329 else:
2330 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2331 main.log.debug( self.name + ": intent ID - " + intentID +
2332 " expected state is " + intentDict[ intentID ] +
2333 " but actual state is " + intentDictONOS[ intentID ] )
2334 returnValue = main.FALSE
2335 intentDictONOS.pop( intentID )
2336 if len( intentDictONOS ) > 0:
2337 returnValue = main.FALSE
2338 for intentID in intentDictONOS.keys():
2339 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002340 if returnValue == main.TRUE:
2341 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2342 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002343 except KeyError:
2344 main.log.exception( self.name + ": KeyError exception found" )
2345 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002346 except ( TypeError, ValueError ):
2347 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002348 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002349 except pexpect.EOF:
2350 main.log.error( self.name + ": EOF exception found" )
2351 main.log.error( self.name + ": " + self.handle.before )
2352 main.cleanup()
2353 main.exit()
2354 except Exception:
2355 main.log.exception( self.name + ": Uncaught exception!" )
2356 main.cleanup()
2357 main.exit()
2358
YPZhang14a4aa92016-07-15 13:37:15 -07002359 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002360 """
2361 Description:
2362 Check the number of installed intents.
2363 Optional:
2364 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002365 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002366 Return:
2367 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2368 , otherwise, returns main.FALSE.
2369 """
2370
2371 try:
2372 cmd = "intents -s -j"
2373
2374 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002375 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002376 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002377 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002378 response = json.loads( response )
2379
2380 # get total and installed number, see if they are match
2381 allState = response.get( 'all' )
2382 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002383 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002384 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002385 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002386 return main.FALSE
2387
Jon Hallc6793552016-01-19 14:18:37 -08002388 except ( TypeError, ValueError ):
2389 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002390 return None
2391 except pexpect.EOF:
2392 main.log.error( self.name + ": EOF exception found" )
2393 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002394 if noExit:
2395 return main.FALSE
2396 else:
2397 main.cleanup()
2398 main.exit()
Jon Halle0f0b342017-04-18 11:43:47 -07002399 except pexpect.TIMEOUT:
2400 main.log.error( self.name + ": ONOS timeout" )
2401 return None
GlennRCed771242016-01-13 17:02:47 -08002402 except Exception:
2403 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002404 if noExit:
2405 return main.FALSE
2406 else:
2407 main.cleanup()
2408 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002409
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002410 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002411 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002412 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002413 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002414 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002415 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002416 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002417 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002418 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002419 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002420 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002421 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002422 if noCore:
2423 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002424 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002425 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002426 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002427 assert "Command not found:" not in handle, handle
2428 if re.search( "Error:", handle ):
2429 main.log.error( self.name + ": flows() response: " +
2430 str( handle ) )
2431 return handle
2432 except AssertionError:
2433 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002434 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002435 except TypeError:
2436 main.log.exception( self.name + ": Object not as expected" )
2437 return None
Jon Hallc6793552016-01-19 14:18:37 -08002438 except pexpect.TIMEOUT:
2439 main.log.error( self.name + ": ONOS timeout" )
2440 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002441 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002442 main.log.error( self.name + ": EOF exception found" )
2443 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002444 main.cleanup()
2445 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002446 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002447 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002448 main.cleanup()
2449 main.exit()
2450
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002451 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002452 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002453 count = int( count ) if count else 0
2454 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002455
Jon Halle0f0b342017-04-18 11:43:47 -07002456 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002457 """
2458 Description:
GlennRCed771242016-01-13 17:02:47 -08002459 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002460 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2461 if the count of those states is 0, which means all current flows
2462 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002463 Optional:
GlennRCed771242016-01-13 17:02:47 -08002464 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002465 Return:
2466 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002467 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002468 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002469 """
2470 try:
GlennRCed771242016-01-13 17:02:47 -08002471 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2472 checkedStates = []
2473 statesCount = [0, 0, 0, 0]
2474 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002475 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002476 if rawFlows:
2477 # if we didn't get flows or flows function return None, we should return
2478 # main.Flase
2479 checkedStates.append( json.loads( rawFlows ) )
2480 else:
2481 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002482 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002483 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002484 try:
2485 statesCount[i] += int( c.get( "flowCount" ) )
2486 except TypeError:
2487 main.log.exception( "Json object not as expected" )
2488 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002489
GlennRCed771242016-01-13 17:02:47 -08002490 # We want to count PENDING_ADD if isPENDING is true
2491 if isPENDING:
2492 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2493 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002494 else:
GlennRCed771242016-01-13 17:02:47 -08002495 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2496 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002497 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002498 except ( TypeError, ValueError ):
2499 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002500 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002501
YPZhang240842b2016-05-17 12:00:50 -07002502 except AssertionError:
2503 main.log.exception( "" )
2504 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002505 except pexpect.TIMEOUT:
2506 main.log.error( self.name + ": ONOS timeout" )
2507 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002508 except pexpect.EOF:
2509 main.log.error( self.name + ": EOF exception found" )
2510 main.log.error( self.name + ": " + self.handle.before )
2511 main.cleanup()
2512 main.exit()
2513 except Exception:
2514 main.log.exception( self.name + ": Uncaught exception!" )
2515 main.cleanup()
2516 main.exit()
2517
GlennRCed771242016-01-13 17:02:47 -08002518 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002519 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002520 """
andrewonlab87852b02014-11-19 18:44:19 -05002521 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002522 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002523 a specific point-to-point intent definition
2524 Required:
GlennRCed771242016-01-13 17:02:47 -08002525 * ingress: specify source dpid
2526 * egress: specify destination dpid
2527 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002528 Optional:
GlennRCed771242016-01-13 17:02:47 -08002529 * offset: the keyOffset is where the next batch of intents
2530 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002531 * noExit: If set to True, TestON will not exit if any error when issus command
2532 * getResponse: If set to True, function will return ONOS response.
2533
GlennRCed771242016-01-13 17:02:47 -08002534 Returns: If failed to push test intents, it will returen None,
2535 if successful, return true.
2536 Timeout expection will return None,
2537 TypeError will return false
2538 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002539 """
andrewonlab87852b02014-11-19 18:44:19 -05002540 try:
GlennRCed771242016-01-13 17:02:47 -08002541 if background:
2542 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002543 else:
GlennRCed771242016-01-13 17:02:47 -08002544 back = ""
2545 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002546 ingress,
2547 egress,
2548 batchSize,
2549 offset,
2550 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002551 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002552 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002553 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002554 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002555 if getResponse:
2556 return response
2557
GlennRCed771242016-01-13 17:02:47 -08002558 # TODO: We should handle if there is failure in installation
2559 return main.TRUE
2560
Jon Hallc6793552016-01-19 14:18:37 -08002561 except AssertionError:
2562 main.log.exception( "" )
2563 return None
GlennRCed771242016-01-13 17:02:47 -08002564 except pexpect.TIMEOUT:
2565 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002566 return None
andrewonlab87852b02014-11-19 18:44:19 -05002567 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002568 main.log.error( self.name + ": EOF exception found" )
2569 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002570 main.cleanup()
2571 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002572 except TypeError:
2573 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002574 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002575 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002576 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002577 main.cleanup()
2578 main.exit()
2579
YPZhangebf9eb52016-05-12 15:20:24 -07002580 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002581 """
2582 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002583 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002584 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002585 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002586 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002587 """
YPZhange3109a72016-02-02 11:25:37 -08002588
YPZhangb5d3f832016-01-23 22:54:26 -08002589 try:
YPZhange3109a72016-02-02 11:25:37 -08002590 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002591 cmd = "flows -c added"
2592 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2593 if rawFlows:
2594 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002595 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002596 for l in rawFlows:
2597 totalFlows += int(l.split("Count=")[1])
2598 else:
2599 main.log.error("Response not as expected!")
2600 return None
2601 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002602
You Wangd3cb2ce2016-05-16 14:01:24 -07002603 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002604 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002605 return None
2606 except pexpect.EOF:
2607 main.log.error( self.name + ": EOF exception found" )
2608 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002609 if not noExit:
2610 main.cleanup()
2611 main.exit()
2612 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002613 except pexpect.TIMEOUT:
2614 main.log.error( self.name + ": ONOS timeout" )
2615 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002616 except Exception:
2617 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002618 if not noExit:
2619 main.cleanup()
2620 main.exit()
2621 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002622
YPZhang14a4aa92016-07-15 13:37:15 -07002623 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002624 """
2625 Description:
2626 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002627 Optional:
2628 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002629 Return:
2630 The number of intents
2631 """
2632 try:
2633 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002634 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002635 if response is None:
2636 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002637 response = json.loads( response )
2638 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002639 except ( TypeError, ValueError ):
2640 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002641 return None
2642 except pexpect.EOF:
2643 main.log.error( self.name + ": EOF exception found" )
2644 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002645 if noExit:
2646 return -1
2647 else:
2648 main.cleanup()
2649 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002650 except Exception:
2651 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002652 if noExit:
2653 return -1
2654 else:
2655 main.cleanup()
2656 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002657
kelvin-onlabd3b64892015-01-20 13:26:24 -08002658 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002659 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002660 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002661 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002662 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002663 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002664 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002665 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002666 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002667 cmdStr += " -j"
2668 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002669 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002670 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002671 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002672 except AssertionError:
2673 main.log.exception( "" )
2674 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002675 except TypeError:
2676 main.log.exception( self.name + ": Object not as expected" )
2677 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002678 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002679 main.log.error( self.name + ": EOF exception found" )
2680 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002681 main.cleanup()
2682 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002683 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002684 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002685 main.cleanup()
2686 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002687
kelvin-onlabd3b64892015-01-20 13:26:24 -08002688 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002689 """
2690 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002691 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002692 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002693 """
andrewonlab867212a2014-10-22 20:13:38 -04002694 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002695 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002696 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002697 cmdStr += " -j"
2698 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002699 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002700 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002701 if handle:
2702 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002703 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002704 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002705 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002706 else:
2707 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002708 except AssertionError:
2709 main.log.exception( "" )
2710 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002711 except TypeError:
2712 main.log.exception( self.name + ": Object not as expected" )
2713 return None
andrewonlab867212a2014-10-22 20:13:38 -04002714 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002715 main.log.error( self.name + ": EOF exception found" )
2716 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002717 main.cleanup()
2718 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002719 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002720 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002721 main.cleanup()
2722 main.exit()
2723
kelvin8ec71442015-01-15 16:57:00 -08002724 # Wrapper functions ****************
2725 # Wrapper functions use existing driver
2726 # functions and extends their use case.
2727 # For example, we may use the output of
2728 # a normal driver function, and parse it
2729 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002730
kelvin-onlabd3b64892015-01-20 13:26:24 -08002731 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002732 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002733 Description:
2734 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002735 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002736 try:
kelvin8ec71442015-01-15 16:57:00 -08002737 # Obtain output of intents function
Jon Hall6021e062017-01-30 11:10:06 -08002738 intentsStr = self.intents(jsonFormat=True)
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002739 if intentsStr is None:
2740 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002741 # Convert to a dictionary
2742 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002743 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002744 for intent in intents:
2745 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002746 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002747 except TypeError:
2748 main.log.exception( self.name + ": Object not as expected" )
2749 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002750 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002751 main.log.error( self.name + ": EOF exception found" )
2752 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002753 main.cleanup()
2754 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002755 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002756 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002757 main.cleanup()
2758 main.exit()
2759
You Wang3c276252016-09-21 15:21:36 -07002760 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002761 """
2762 Determine the number of flow rules for the given device id that are
2763 in the added state
You Wang3c276252016-09-21 15:21:36 -07002764 Params:
2765 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002766 """
2767 try:
You Wang3c276252016-09-21 15:21:36 -07002768 if core:
2769 cmdStr = "flows any " + str( deviceId ) + " | " +\
2770 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2771 else:
2772 cmdStr = "flows any " + str( deviceId ) + " | " +\
2773 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002774 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002775 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002776 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002777 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002778 except AssertionError:
2779 main.log.exception( "" )
2780 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002781 except pexpect.EOF:
2782 main.log.error( self.name + ": EOF exception found" )
2783 main.log.error( self.name + ": " + self.handle.before )
2784 main.cleanup()
2785 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002786 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002787 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002788 main.cleanup()
2789 main.exit()
2790
kelvin-onlabd3b64892015-01-20 13:26:24 -08002791 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002792 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002793 Use 'devices' function to obtain list of all devices
2794 and parse the result to obtain a list of all device
2795 id's. Returns this list. Returns empty list if no
2796 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002797 List is ordered sequentially
2798
andrewonlab3e15ead2014-10-15 14:21:34 -04002799 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002800 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002801 the ids. By obtaining the list of device ids on the fly,
2802 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002803 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002804 try:
kelvin8ec71442015-01-15 16:57:00 -08002805 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002806 devicesStr = self.devices( jsonFormat=False )
2807 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002808
kelvin-onlabd3b64892015-01-20 13:26:24 -08002809 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002810 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002811 return idList
kelvin8ec71442015-01-15 16:57:00 -08002812
2813 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002814 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002815 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002816 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002817 # Split list further into arguments before and after string
2818 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002819 # append to idList
2820 for arg in tempList:
2821 idList.append( arg.split( "id=" )[ 1 ] )
2822 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002823
Jon Halld4d4b372015-01-28 16:02:41 -08002824 except TypeError:
2825 main.log.exception( self.name + ": Object not as expected" )
2826 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002827 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002828 main.log.error( self.name + ": EOF exception found" )
2829 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002830 main.cleanup()
2831 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002832 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002833 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002834 main.cleanup()
2835 main.exit()
2836
kelvin-onlabd3b64892015-01-20 13:26:24 -08002837 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002838 """
andrewonlab7c211572014-10-15 16:45:20 -04002839 Uses 'nodes' function to obtain list of all nodes
2840 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002841 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002842 Returns:
2843 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002844 """
andrewonlab7c211572014-10-15 16:45:20 -04002845 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002846 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002847 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002848 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002849 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002850 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002851 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002852 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002853 nodesJson = json.loads( nodesStr )
2854 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002855 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002856 except ( TypeError, ValueError ):
2857 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002858 return None
andrewonlab7c211572014-10-15 16:45:20 -04002859 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002860 main.log.error( self.name + ": EOF exception found" )
2861 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002862 main.cleanup()
2863 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002864 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002865 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002866 main.cleanup()
2867 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002868
kelvin-onlabd3b64892015-01-20 13:26:24 -08002869 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002870 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002871 Return the first device from the devices api whose 'id' contains 'dpid'
2872 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002873 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002874 try:
kelvin8ec71442015-01-15 16:57:00 -08002875 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002876 return None
2877 else:
kelvin8ec71442015-01-15 16:57:00 -08002878 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002879 rawDevices = self.devices()
2880 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002881 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002882 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002883 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2884 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002885 return device
2886 return None
Jon Hallc6793552016-01-19 14:18:37 -08002887 except ( TypeError, ValueError ):
2888 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002889 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002890 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002891 main.log.error( self.name + ": EOF exception found" )
2892 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002893 main.cleanup()
2894 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002895 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002896 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002897 main.cleanup()
2898 main.exit()
2899
You Wang24139872016-05-03 11:48:47 -07002900 def getTopology( self, topologyOutput ):
2901 """
2902 Definition:
2903 Loads a json topology output
2904 Return:
2905 topology = current ONOS topology
2906 """
2907 import json
2908 try:
2909 # either onos:topology or 'topology' will work in CLI
2910 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002911 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002912 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002913 except ( TypeError, ValueError ):
2914 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2915 return None
You Wang24139872016-05-03 11:48:47 -07002916 except pexpect.EOF:
2917 main.log.error( self.name + ": EOF exception found" )
2918 main.log.error( self.name + ": " + self.handle.before )
2919 main.cleanup()
2920 main.exit()
2921 except Exception:
2922 main.log.exception( self.name + ": Uncaught exception!" )
2923 main.cleanup()
2924 main.exit()
2925
Flavio Castro82ee2f62016-06-07 15:04:12 -07002926 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002927 """
Jon Hallefbd9792015-03-05 16:11:36 -08002928 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002929 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002930 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002931
Flavio Castro82ee2f62016-06-07 15:04:12 -07002932 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002933 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002934 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002935 logLevel = level to log to.
2936 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002937
Jon Hallefbd9792015-03-05 16:11:36 -08002938 Returns: main.TRUE if the number of switches and links are correct,
2939 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002940 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002941 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002942 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002943 try:
You Wang13310252016-07-31 10:56:14 -07002944 summary = self.summary()
2945 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002946 except ( TypeError, ValueError ):
2947 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2948 return main.ERROR
2949 try:
2950 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07002951 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002952 return main.ERROR
2953 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002954 # Is the number of switches is what we expected
2955 devices = topology.get( 'devices', False )
2956 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002957 nodes = summary.get( 'nodes', False )
2958 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002959 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002960 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002961 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002962 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002963 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2964 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002965 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002966 output = output + "The number of links and switches match "\
2967 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002968 result = main.TRUE
2969 else:
You Wang24139872016-05-03 11:48:47 -07002970 output = output + \
2971 "The number of links and switches does not match " + \
2972 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002973 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002974 output = output + "\n ONOS sees %i devices" % int( devices )
2975 output = output + " (%i expected) " % int( numoswitch )
2976 output = output + "and %i links " % int( links )
2977 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002978 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002979 output = output + "and %i controllers " % int( nodes )
2980 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002981 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002982 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002983 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002984 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002985 else:
You Wang24139872016-05-03 11:48:47 -07002986 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002987 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002988 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002989 main.log.error( self.name + ": EOF exception found" )
2990 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04002991 main.cleanup()
2992 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002993 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002994 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04002995 main.cleanup()
2996 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002997
kelvin-onlabd3b64892015-01-20 13:26:24 -08002998 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002999 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003000 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003001 deviceId must be the id of a device as seen in the onos devices command
3002 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003003 role must be either master, standby, or none
3004
Jon Halle3f39ff2015-01-13 11:50:53 -08003005 Returns:
3006 main.TRUE or main.FALSE based on argument verification and
3007 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003008 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003009 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003010 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003011 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003012 cmdStr = "device-role " +\
3013 str( deviceId ) + " " +\
3014 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003015 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003016 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003017 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003018 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003019 if re.search( "Error", handle ):
3020 # end color output to escape any colours
3021 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003022 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003023 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003024 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003025 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003026 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003027 main.log.error( "Invalid 'role' given to device_role(). " +
3028 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003029 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003030 except AssertionError:
3031 main.log.exception( "" )
3032 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003033 except TypeError:
3034 main.log.exception( self.name + ": Object not as expected" )
3035 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003036 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003037 main.log.error( self.name + ": EOF exception found" )
3038 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04003039 main.cleanup()
3040 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003041 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003042 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04003043 main.cleanup()
3044 main.exit()
3045
kelvin-onlabd3b64892015-01-20 13:26:24 -08003046 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003047 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003048 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003049 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003050 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003051 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003052 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003053 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003054 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003055 cmdStr += " -j"
3056 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003057 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003058 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003059 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003060 except AssertionError:
3061 main.log.exception( "" )
3062 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003063 except TypeError:
3064 main.log.exception( self.name + ": Object not as expected" )
3065 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003066 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003067 main.log.error( self.name + ": EOF exception found" )
3068 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003069 main.cleanup()
3070 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003071 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003072 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003073 main.cleanup()
3074 main.exit()
3075
kelvin-onlabd3b64892015-01-20 13:26:24 -08003076 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003077 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003078 CLI command to get the current leader for the Election test application
3079 NOTE: Requires installation of the onos-app-election feature
3080 Returns: Node IP of the leader if one exists
3081 None if none exists
3082 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003083 """
Jon Hall94fd0472014-12-08 11:52:42 -08003084 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003085 cmdStr = "election-test-leader"
3086 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003087 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003088 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003089 # Leader
3090 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003091 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003092 nodeSearch = re.search( leaderPattern, response )
3093 if nodeSearch:
3094 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003095 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003096 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003097 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003098 # no leader
3099 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003100 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003101 nullSearch = re.search( nullPattern, response )
3102 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003103 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003104 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003105 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003106 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003107 main.log.error( "Error in electionTestLeader on " + self.name +
3108 ": " + "unexpected response" )
3109 main.log.error( repr( response ) )
3110 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003111 except AssertionError:
3112 main.log.exception( "" )
3113 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003114 except TypeError:
3115 main.log.exception( self.name + ": Object not as expected" )
3116 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003117 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003118 main.log.error( self.name + ": EOF exception found" )
3119 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003120 main.cleanup()
3121 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003122 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003123 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003124 main.cleanup()
3125 main.exit()
3126
kelvin-onlabd3b64892015-01-20 13:26:24 -08003127 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003128 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003129 CLI command to run for leadership of the Election test application.
3130 NOTE: Requires installation of the onos-app-election feature
3131 Returns: Main.TRUE on success
3132 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003133 """
Jon Hall94fd0472014-12-08 11:52:42 -08003134 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003135 cmdStr = "election-test-run"
3136 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003137 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003138 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003139 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003140 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003141 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003142 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003143 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003144 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003145 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003146 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003147 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003148 main.log.error( "Error in electionTestRun on " + self.name +
3149 ": " + "unexpected response" )
3150 main.log.error( repr( response ) )
3151 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003152 except AssertionError:
3153 main.log.exception( "" )
3154 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003155 except TypeError:
3156 main.log.exception( self.name + ": Object not as expected" )
3157 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003158 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003159 main.log.error( self.name + ": EOF exception found" )
3160 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003161 main.cleanup()
3162 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003163 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003164 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003165 main.cleanup()
3166 main.exit()
3167
kelvin-onlabd3b64892015-01-20 13:26:24 -08003168 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003169 """
Jon Hall94fd0472014-12-08 11:52:42 -08003170 * CLI command to withdraw the local node from leadership election for
3171 * the Election test application.
3172 #NOTE: Requires installation of the onos-app-election feature
3173 Returns: Main.TRUE on success
3174 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003175 """
Jon Hall94fd0472014-12-08 11:52:42 -08003176 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003177 cmdStr = "election-test-withdraw"
3178 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003179 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003180 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003181 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003182 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003183 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003184 if re.search( successPattern, response ):
3185 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003186 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003187 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003188 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003189 main.log.error( "Error in electionTestWithdraw on " +
3190 self.name + ": " + "unexpected response" )
3191 main.log.error( repr( response ) )
3192 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003193 except AssertionError:
3194 main.log.exception( "" )
3195 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003196 except TypeError:
3197 main.log.exception( self.name + ": Object not as expected" )
3198 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003199 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003200 main.log.error( self.name + ": EOF exception found" )
3201 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003202 main.cleanup()
3203 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003204 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003205 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003206 main.cleanup()
3207 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003208
kelvin8ec71442015-01-15 16:57:00 -08003209 def getDevicePortsEnabledCount( self, dpid ):
3210 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003211 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003212 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003213 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003214 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003215 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3216 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003217 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003218 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003219 if re.search( "No such device", output ):
3220 main.log.error( "Error in getting ports" )
3221 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003222 return output
Jon Hallc6793552016-01-19 14:18:37 -08003223 except AssertionError:
3224 main.log.exception( "" )
3225 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003226 except TypeError:
3227 main.log.exception( self.name + ": Object not as expected" )
3228 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003229 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003230 main.log.error( self.name + ": EOF exception found" )
3231 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003232 main.cleanup()
3233 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003234 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003235 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003236 main.cleanup()
3237 main.exit()
3238
kelvin8ec71442015-01-15 16:57:00 -08003239 def getDeviceLinksActiveCount( self, dpid ):
3240 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003241 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003242 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003243 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003244 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003245 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3246 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003247 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003248 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003249 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003250 main.log.error( "Error in getting ports " )
3251 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003252 return output
Jon Hallc6793552016-01-19 14:18:37 -08003253 except AssertionError:
3254 main.log.exception( "" )
3255 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003256 except TypeError:
3257 main.log.exception( self.name + ": Object not as expected" )
3258 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003259 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003260 main.log.error( self.name + ": EOF exception found" )
3261 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003262 main.cleanup()
3263 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003264 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003265 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003266 main.cleanup()
3267 main.exit()
3268
kelvin8ec71442015-01-15 16:57:00 -08003269 def getAllIntentIds( self ):
3270 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003271 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003272 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003273 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003274 cmdStr = "onos:intents | grep id="
3275 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003276 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003277 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003278 if re.search( "Error", output ):
3279 main.log.error( "Error in getting ports" )
3280 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003281 return output
Jon Hallc6793552016-01-19 14:18:37 -08003282 except AssertionError:
3283 main.log.exception( "" )
3284 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003285 except TypeError:
3286 main.log.exception( self.name + ": Object not as expected" )
3287 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003288 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003289 main.log.error( self.name + ": EOF exception found" )
3290 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003291 main.cleanup()
3292 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003293 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003294 main.log.exception( self.name + ": Uncaught exception!" )
3295 main.cleanup()
3296 main.exit()
3297
Jon Hall73509952015-02-24 16:42:56 -08003298 def intentSummary( self ):
3299 """
Jon Hallefbd9792015-03-05 16:11:36 -08003300 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003301 """
3302 try:
3303 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003304 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003305 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003306 states.append( intent.get( 'state', None ) )
3307 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003308 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003309 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003310 except ( TypeError, ValueError ):
3311 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003312 return None
3313 except pexpect.EOF:
3314 main.log.error( self.name + ": EOF exception found" )
3315 main.log.error( self.name + ": " + self.handle.before )
3316 main.cleanup()
3317 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003318 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003319 main.log.exception( self.name + ": Uncaught exception!" )
3320 main.cleanup()
3321 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003322
Jon Hall61282e32015-03-19 11:34:11 -07003323 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003324 """
3325 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003326 Optional argument:
3327 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003328 """
Jon Hall63604932015-02-26 17:09:50 -08003329 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003330 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003331 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003332 cmdStr += " -j"
3333 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003334 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003335 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003336 return output
Jon Hallc6793552016-01-19 14:18:37 -08003337 except AssertionError:
3338 main.log.exception( "" )
3339 return None
Jon Hall63604932015-02-26 17:09:50 -08003340 except TypeError:
3341 main.log.exception( self.name + ": Object not as expected" )
3342 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003343 except pexpect.EOF:
3344 main.log.error( self.name + ": EOF exception found" )
3345 main.log.error( self.name + ": " + self.handle.before )
3346 main.cleanup()
3347 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003348 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003349 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003350 main.cleanup()
3351 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003352
acsmarsa4a4d1e2015-07-10 16:01:24 -07003353 def leaderCandidates( self, jsonFormat=True ):
3354 """
3355 Returns the output of the leaders -c command.
3356 Optional argument:
3357 * jsonFormat - boolean indicating if you want output in json
3358 """
3359 try:
3360 cmdStr = "onos:leaders -c"
3361 if jsonFormat:
3362 cmdStr += " -j"
3363 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003364 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003365 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003366 return output
Jon Hallc6793552016-01-19 14:18:37 -08003367 except AssertionError:
3368 main.log.exception( "" )
3369 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003370 except TypeError:
3371 main.log.exception( self.name + ": Object not as expected" )
3372 return None
3373 except pexpect.EOF:
3374 main.log.error( self.name + ": EOF exception found" )
3375 main.log.error( self.name + ": " + self.handle.before )
3376 main.cleanup()
3377 main.exit()
3378 except Exception:
3379 main.log.exception( self.name + ": Uncaught exception!" )
3380 main.cleanup()
3381 main.exit()
3382
Jon Hallc6793552016-01-19 14:18:37 -08003383 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003384 """
3385 Returns a list in format [leader,candidate1,candidate2,...] for a given
3386 topic parameter and an empty list if the topic doesn't exist
3387 If no leader is elected leader in the returned list will be "none"
3388 Returns None if there is a type error processing the json object
3389 """
3390 try:
Jon Hall6e709752016-02-01 13:38:46 -08003391 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003392 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003393 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003394 assert "Command not found:" not in rawOutput, rawOutput
3395 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003396 results = []
3397 for dict in output:
3398 if dict["topic"] == topic:
3399 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003400 candidates = re.split( ", ", dict["candidates"][1:-1] )
3401 results.append( leader )
3402 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003403 return results
Jon Hallc6793552016-01-19 14:18:37 -08003404 except AssertionError:
3405 main.log.exception( "" )
3406 return None
3407 except ( TypeError, ValueError ):
3408 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003409 return None
3410 except pexpect.EOF:
3411 main.log.error( self.name + ": EOF exception found" )
3412 main.log.error( self.name + ": " + self.handle.before )
3413 main.cleanup()
3414 main.exit()
3415 except Exception:
3416 main.log.exception( self.name + ": Uncaught exception!" )
3417 main.cleanup()
3418 main.exit()
3419
Jon Hall61282e32015-03-19 11:34:11 -07003420 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003421 """
3422 Returns the output of the intent Pending map.
3423 """
Jon Hall63604932015-02-26 17:09:50 -08003424 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003425 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003426 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003427 cmdStr += " -j"
3428 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003429 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003430 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003431 return output
Jon Hallc6793552016-01-19 14:18:37 -08003432 except AssertionError:
3433 main.log.exception( "" )
3434 return None
Jon Hall63604932015-02-26 17:09:50 -08003435 except TypeError:
3436 main.log.exception( self.name + ": Object not as expected" )
3437 return None
3438 except pexpect.EOF:
3439 main.log.error( self.name + ": EOF exception found" )
3440 main.log.error( self.name + ": " + self.handle.before )
3441 main.cleanup()
3442 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003443 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003444 main.log.exception( self.name + ": Uncaught exception!" )
3445 main.cleanup()
3446 main.exit()
3447
Jon Hall2c8959e2016-12-16 12:17:34 -08003448 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003449 """
3450 Returns the output of the raft partitions command for ONOS.
3451 """
Jon Hall61282e32015-03-19 11:34:11 -07003452 # Sample JSON
3453 # {
3454 # "leader": "tcp://10.128.30.11:7238",
3455 # "members": [
3456 # "tcp://10.128.30.11:7238",
3457 # "tcp://10.128.30.17:7238",
3458 # "tcp://10.128.30.13:7238",
3459 # ],
3460 # "name": "p1",
3461 # "term": 3
3462 # },
Jon Hall63604932015-02-26 17:09:50 -08003463 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003464 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003465 if candidates:
3466 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003467 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003468 cmdStr += " -j"
3469 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003470 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003471 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003472 return output
Jon Hallc6793552016-01-19 14:18:37 -08003473 except AssertionError:
3474 main.log.exception( "" )
3475 return None
Jon Hall63604932015-02-26 17:09:50 -08003476 except TypeError:
3477 main.log.exception( self.name + ": Object not as expected" )
3478 return None
3479 except pexpect.EOF:
3480 main.log.error( self.name + ": EOF exception found" )
3481 main.log.error( self.name + ": " + self.handle.before )
3482 main.cleanup()
3483 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003484 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003485 main.log.exception( self.name + ": Uncaught exception!" )
3486 main.cleanup()
3487 main.exit()
3488
Jon Halle9f909e2016-09-23 10:43:12 -07003489 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003490 """
3491 Returns the output of the apps command for ONOS. This command lists
3492 information about installed ONOS applications
3493 """
3494 # Sample JSON object
3495 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3496 # "description":"ONOS OpenFlow protocol southbound providers",
3497 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3498 # "features":"[onos-openflow]","state":"ACTIVE"}]
3499 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003500 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003501 if summary:
3502 cmdStr += " -s"
3503 if active:
3504 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003505 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003506 cmdStr += " -j"
3507 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003508 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003509 assert "Command not found:" not in output, output
3510 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003511 return output
Jon Hallbe379602015-03-24 13:39:32 -07003512 # FIXME: look at specific exceptions/Errors
3513 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003514 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003515 return None
3516 except TypeError:
3517 main.log.exception( self.name + ": Object not as expected" )
3518 return None
3519 except pexpect.EOF:
3520 main.log.error( self.name + ": EOF exception found" )
3521 main.log.error( self.name + ": " + self.handle.before )
3522 main.cleanup()
3523 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003524 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003525 main.log.exception( self.name + ": Uncaught exception!" )
3526 main.cleanup()
3527 main.exit()
3528
Jon Hall146f1522015-03-24 15:33:24 -07003529 def appStatus( self, appName ):
3530 """
3531 Uses the onos:apps cli command to return the status of an application.
3532 Returns:
3533 "ACTIVE" - If app is installed and activated
3534 "INSTALLED" - If app is installed and deactivated
3535 "UNINSTALLED" - If app is not installed
3536 None - on error
3537 """
Jon Hall146f1522015-03-24 15:33:24 -07003538 try:
3539 if not isinstance( appName, types.StringType ):
3540 main.log.error( self.name + ".appStatus(): appName must be" +
3541 " a string" )
3542 return None
3543 output = self.apps( jsonFormat=True )
3544 appsJson = json.loads( output )
3545 state = None
3546 for app in appsJson:
3547 if appName == app.get('name'):
3548 state = app.get('state')
3549 break
3550 if state == "ACTIVE" or state == "INSTALLED":
3551 return state
3552 elif state is None:
3553 return "UNINSTALLED"
3554 elif state:
3555 main.log.error( "Unexpected state from 'onos:apps': " +
3556 str( state ) )
3557 return state
Jon Hallc6793552016-01-19 14:18:37 -08003558 except ( TypeError, ValueError ):
3559 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003560 return None
3561 except pexpect.EOF:
3562 main.log.error( self.name + ": EOF exception found" )
3563 main.log.error( self.name + ": " + self.handle.before )
3564 main.cleanup()
3565 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003566 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003567 main.log.exception( self.name + ": Uncaught exception!" )
3568 main.cleanup()
3569 main.exit()
3570
Jon Hallbe379602015-03-24 13:39:32 -07003571 def app( self, appName, option ):
3572 """
3573 Interacts with the app command for ONOS. This command manages
3574 application inventory.
3575 """
Jon Hallbe379602015-03-24 13:39:32 -07003576 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003577 # Validate argument types
3578 valid = True
3579 if not isinstance( appName, types.StringType ):
3580 main.log.error( self.name + ".app(): appName must be a " +
3581 "string" )
3582 valid = False
3583 if not isinstance( option, types.StringType ):
3584 main.log.error( self.name + ".app(): option must be a string" )
3585 valid = False
3586 if not valid:
3587 return main.FALSE
3588 # Validate Option
3589 option = option.lower()
3590 # NOTE: Install may become a valid option
3591 if option == "activate":
3592 pass
3593 elif option == "deactivate":
3594 pass
3595 elif option == "uninstall":
3596 pass
3597 else:
3598 # Invalid option
3599 main.log.error( "The ONOS app command argument only takes " +
3600 "the values: (activate|deactivate|uninstall)" +
3601 "; was given '" + option + "'")
3602 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003603 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003604 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003605 assert output is not None, "Error in sendline"
3606 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003607 if "Error executing command" in output:
3608 main.log.error( "Error in processing onos:app command: " +
3609 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003610 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003611 elif "No such application" in output:
3612 main.log.error( "The application '" + appName +
3613 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003614 return main.FALSE
3615 elif "Command not found:" in output:
3616 main.log.error( "Error in processing onos:app command: " +
3617 str( output ) )
3618 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003619 elif "Unsupported command:" in output:
3620 main.log.error( "Incorrect command given to 'app': " +
3621 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003622 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003623 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003624 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003625 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003626 except AssertionError:
3627 main.log.exception( self.name + ": AssertionError exception found" )
3628 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003629 except TypeError:
3630 main.log.exception( self.name + ": Object not as expected" )
3631 return main.ERROR
3632 except pexpect.EOF:
3633 main.log.error( self.name + ": EOF exception found" )
3634 main.log.error( self.name + ": " + self.handle.before )
3635 main.cleanup()
3636 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003637 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003638 main.log.exception( self.name + ": Uncaught exception!" )
3639 main.cleanup()
3640 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003641
Jon Hallbd16b922015-03-26 17:53:15 -07003642 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003643 """
3644 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003645 appName is the hierarchical app name, not the feature name
3646 If check is True, method will check the status of the app after the
3647 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003648 Returns main.TRUE if the command was successfully sent
3649 main.FALSE if the cli responded with an error or given
3650 incorrect input
3651 """
3652 try:
3653 if not isinstance( appName, types.StringType ):
3654 main.log.error( self.name + ".activateApp(): appName must be" +
3655 " a string" )
3656 return main.FALSE
3657 status = self.appStatus( appName )
3658 if status == "INSTALLED":
3659 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003660 if check and response == main.TRUE:
3661 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003662 status = self.appStatus( appName )
3663 if status == "ACTIVE":
3664 return main.TRUE
3665 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003666 main.log.debug( "The state of application " +
3667 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003668 time.sleep( 1 )
3669 return main.FALSE
3670 else: # not 'check' or command didn't succeed
3671 return response
Jon Hall146f1522015-03-24 15:33:24 -07003672 elif status == "ACTIVE":
3673 return main.TRUE
3674 elif status == "UNINSTALLED":
3675 main.log.error( self.name + ": Tried to activate the " +
3676 "application '" + appName + "' which is not " +
3677 "installed." )
3678 else:
3679 main.log.error( "Unexpected return value from appStatus: " +
3680 str( status ) )
3681 return main.ERROR
3682 except TypeError:
3683 main.log.exception( self.name + ": Object not as expected" )
3684 return main.ERROR
3685 except pexpect.EOF:
3686 main.log.error( self.name + ": EOF exception found" )
3687 main.log.error( self.name + ": " + self.handle.before )
3688 main.cleanup()
3689 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003690 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003691 main.log.exception( self.name + ": Uncaught exception!" )
3692 main.cleanup()
3693 main.exit()
3694
Jon Hallbd16b922015-03-26 17:53:15 -07003695 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003696 """
3697 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003698 appName is the hierarchical app name, not the feature name
3699 If check is True, method will check the status of the app after the
3700 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003701 Returns main.TRUE if the command was successfully sent
3702 main.FALSE if the cli responded with an error or given
3703 incorrect input
3704 """
3705 try:
3706 if not isinstance( appName, types.StringType ):
3707 main.log.error( self.name + ".deactivateApp(): appName must " +
3708 "be a string" )
3709 return main.FALSE
3710 status = self.appStatus( appName )
3711 if status == "INSTALLED":
3712 return main.TRUE
3713 elif status == "ACTIVE":
3714 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003715 if check and response == main.TRUE:
3716 for i in range(10): # try 10 times then give up
3717 status = self.appStatus( appName )
3718 if status == "INSTALLED":
3719 return main.TRUE
3720 else:
3721 time.sleep( 1 )
3722 return main.FALSE
3723 else: # not check or command didn't succeed
3724 return response
Jon Hall146f1522015-03-24 15:33:24 -07003725 elif status == "UNINSTALLED":
3726 main.log.warn( self.name + ": Tried to deactivate the " +
3727 "application '" + appName + "' which is not " +
3728 "installed." )
3729 return main.TRUE
3730 else:
3731 main.log.error( "Unexpected return value from appStatus: " +
3732 str( status ) )
3733 return main.ERROR
3734 except TypeError:
3735 main.log.exception( self.name + ": Object not as expected" )
3736 return main.ERROR
3737 except pexpect.EOF:
3738 main.log.error( self.name + ": EOF exception found" )
3739 main.log.error( self.name + ": " + self.handle.before )
3740 main.cleanup()
3741 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003742 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003743 main.log.exception( self.name + ": Uncaught exception!" )
3744 main.cleanup()
3745 main.exit()
3746
Jon Hallbd16b922015-03-26 17:53:15 -07003747 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003748 """
3749 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003750 appName is the hierarchical app name, not the feature name
3751 If check is True, method will check the status of the app after the
3752 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003753 Returns main.TRUE if the command was successfully sent
3754 main.FALSE if the cli responded with an error or given
3755 incorrect input
3756 """
3757 # TODO: check with Thomas about the state machine for apps
3758 try:
3759 if not isinstance( appName, types.StringType ):
3760 main.log.error( self.name + ".uninstallApp(): appName must " +
3761 "be a string" )
3762 return main.FALSE
3763 status = self.appStatus( appName )
3764 if status == "INSTALLED":
3765 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003766 if check and response == main.TRUE:
3767 for i in range(10): # try 10 times then give up
3768 status = self.appStatus( appName )
3769 if status == "UNINSTALLED":
3770 return main.TRUE
3771 else:
3772 time.sleep( 1 )
3773 return main.FALSE
3774 else: # not check or command didn't succeed
3775 return response
Jon Hall146f1522015-03-24 15:33:24 -07003776 elif status == "ACTIVE":
3777 main.log.warn( self.name + ": Tried to uninstall the " +
3778 "application '" + appName + "' which is " +
3779 "currently active." )
3780 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003781 if check and response == main.TRUE:
3782 for i in range(10): # try 10 times then give up
3783 status = self.appStatus( appName )
3784 if status == "UNINSTALLED":
3785 return main.TRUE
3786 else:
3787 time.sleep( 1 )
3788 return main.FALSE
3789 else: # not check or command didn't succeed
3790 return response
Jon Hall146f1522015-03-24 15:33:24 -07003791 elif status == "UNINSTALLED":
3792 return main.TRUE
3793 else:
3794 main.log.error( "Unexpected return value from appStatus: " +
3795 str( status ) )
3796 return main.ERROR
3797 except TypeError:
3798 main.log.exception( self.name + ": Object not as expected" )
3799 return main.ERROR
3800 except pexpect.EOF:
3801 main.log.error( self.name + ": EOF exception found" )
3802 main.log.error( self.name + ": " + self.handle.before )
3803 main.cleanup()
3804 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003805 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003806 main.log.exception( self.name + ": Uncaught exception!" )
3807 main.cleanup()
3808 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003809
3810 def appIDs( self, jsonFormat=True ):
3811 """
3812 Show the mappings between app id and app names given by the 'app-ids'
3813 cli command
3814 """
3815 try:
3816 cmdStr = "app-ids"
3817 if jsonFormat:
3818 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003819 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003820 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003821 assert "Command not found:" not in output, output
3822 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003823 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003824 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003825 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003826 return None
3827 except TypeError:
3828 main.log.exception( self.name + ": Object not as expected" )
3829 return None
3830 except pexpect.EOF:
3831 main.log.error( self.name + ": EOF exception found" )
3832 main.log.error( self.name + ": " + self.handle.before )
3833 main.cleanup()
3834 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003835 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003836 main.log.exception( self.name + ": Uncaught exception!" )
3837 main.cleanup()
3838 main.exit()
3839
3840 def appToIDCheck( self ):
3841 """
3842 This method will check that each application's ID listed in 'apps' is
3843 the same as the ID listed in 'app-ids'. The check will also check that
3844 there are no duplicate IDs issued. Note that an app ID should be
3845 a globaly unique numerical identifier for app/app-like features. Once
3846 an ID is registered, the ID is never freed up so that if an app is
3847 reinstalled it will have the same ID.
3848
3849 Returns: main.TRUE if the check passes and
3850 main.FALSE if the check fails or
3851 main.ERROR if there is some error in processing the test
3852 """
3853 try:
Jon Hall390696c2015-05-05 17:13:41 -07003854 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003855 rawJson = self.appIDs( jsonFormat=True )
3856 if rawJson:
3857 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003858 else:
Jon Hallc6793552016-01-19 14:18:37 -08003859 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003860 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003861 rawJson = self.apps( jsonFormat=True )
3862 if rawJson:
3863 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003864 else:
Jon Hallc6793552016-01-19 14:18:37 -08003865 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003866 bail = True
3867 if bail:
3868 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003869 result = main.TRUE
3870 for app in apps:
3871 appID = app.get( 'id' )
3872 if appID is None:
3873 main.log.error( "Error parsing app: " + str( app ) )
3874 result = main.FALSE
3875 appName = app.get( 'name' )
3876 if appName is None:
3877 main.log.error( "Error parsing app: " + str( app ) )
3878 result = main.FALSE
3879 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003880 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003881 # main.log.debug( "Comparing " + str( app ) + " to " +
3882 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003883 if not current: # if ids doesn't have this id
3884 result = main.FALSE
3885 main.log.error( "'app-ids' does not have the ID for " +
3886 str( appName ) + " that apps does." )
3887 elif len( current ) > 1:
3888 # there is more than one app with this ID
3889 result = main.FALSE
3890 # We will log this later in the method
3891 elif not current[0][ 'name' ] == appName:
3892 currentName = current[0][ 'name' ]
3893 result = main.FALSE
3894 main.log.error( "'app-ids' has " + str( currentName ) +
3895 " registered under id:" + str( appID ) +
3896 " but 'apps' has " + str( appName ) )
3897 else:
3898 pass # id and name match!
3899 # now make sure that app-ids has no duplicates
3900 idsList = []
3901 namesList = []
3902 for item in ids:
3903 idsList.append( item[ 'id' ] )
3904 namesList.append( item[ 'name' ] )
3905 if len( idsList ) != len( set( idsList ) ) or\
3906 len( namesList ) != len( set( namesList ) ):
3907 main.log.error( "'app-ids' has some duplicate entries: \n"
3908 + json.dumps( ids,
3909 sort_keys=True,
3910 indent=4,
3911 separators=( ',', ': ' ) ) )
3912 result = main.FALSE
3913 return result
Jon Hallc6793552016-01-19 14:18:37 -08003914 except ( TypeError, ValueError ):
3915 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003916 return main.ERROR
3917 except pexpect.EOF:
3918 main.log.error( self.name + ": EOF exception found" )
3919 main.log.error( self.name + ": " + self.handle.before )
3920 main.cleanup()
3921 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003922 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003923 main.log.exception( self.name + ": Uncaught exception!" )
3924 main.cleanup()
3925 main.exit()
3926
Jon Hallfb760a02015-04-13 15:35:03 -07003927 def getCfg( self, component=None, propName=None, short=False,
3928 jsonFormat=True ):
3929 """
3930 Get configuration settings from onos cli
3931 Optional arguments:
3932 component - Optionally only list configurations for a specific
3933 component. If None, all components with configurations
3934 are displayed. Case Sensitive string.
3935 propName - If component is specified, propName option will show
3936 only this specific configuration from that component.
3937 Case Sensitive string.
3938 jsonFormat - Returns output as json. Note that this will override
3939 the short option
3940 short - Short, less verbose, version of configurations.
3941 This is overridden by the json option
3942 returns:
3943 Output from cli as a string or None on error
3944 """
3945 try:
3946 baseStr = "cfg"
3947 cmdStr = " get"
3948 componentStr = ""
3949 if component:
3950 componentStr += " " + component
3951 if propName:
3952 componentStr += " " + propName
3953 if jsonFormat:
3954 baseStr += " -j"
3955 elif short:
3956 baseStr += " -s"
3957 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003958 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003959 assert "Command not found:" not in output, output
3960 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003961 return output
3962 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003963 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003964 return None
3965 except TypeError:
3966 main.log.exception( self.name + ": Object not as expected" )
3967 return None
3968 except pexpect.EOF:
3969 main.log.error( self.name + ": EOF exception found" )
3970 main.log.error( self.name + ": " + self.handle.before )
3971 main.cleanup()
3972 main.exit()
3973 except Exception:
3974 main.log.exception( self.name + ": Uncaught exception!" )
3975 main.cleanup()
3976 main.exit()
3977
3978 def setCfg( self, component, propName, value=None, check=True ):
3979 """
3980 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003981 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003982 component - The case sensitive name of the component whose
3983 property is to be set
3984 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003985 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003986 value - The value to set the property to. If None, will unset the
3987 property and revert it to it's default value(if applicable)
3988 check - Boolean, Check whether the option was successfully set this
3989 only applies when a value is given.
3990 returns:
3991 main.TRUE on success or main.FALSE on failure. If check is False,
3992 will return main.TRUE unless there is an error
3993 """
3994 try:
3995 baseStr = "cfg"
3996 cmdStr = " set " + str( component ) + " " + str( propName )
3997 if value is not None:
3998 cmdStr += " " + str( value )
3999 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004000 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004001 assert "Command not found:" not in output, output
4002 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004003 if value and check:
4004 results = self.getCfg( component=str( component ),
4005 propName=str( propName ),
4006 jsonFormat=True )
4007 # Check if current value is what we just set
4008 try:
4009 jsonOutput = json.loads( results )
4010 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004011 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004012 main.log.exception( "Error parsing cfg output" )
4013 main.log.error( "output:" + repr( results ) )
4014 return main.FALSE
4015 if current == str( value ):
4016 return main.TRUE
4017 return main.FALSE
4018 return main.TRUE
4019 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004020 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004021 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004022 except ( TypeError, ValueError ):
4023 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004024 return main.FALSE
4025 except pexpect.EOF:
4026 main.log.error( self.name + ": EOF exception found" )
4027 main.log.error( self.name + ": " + self.handle.before )
4028 main.cleanup()
4029 main.exit()
4030 except Exception:
4031 main.log.exception( self.name + ": Uncaught exception!" )
4032 main.cleanup()
4033 main.exit()
4034
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004035 def distPrimitivesSend( self, cmd ):
4036 """
4037 Function to handle sending cli commands for the distributed primitives test app
4038
4039 This command will catch some exceptions and retry the command on some
4040 specific store exceptions.
4041
4042 Required arguments:
4043 cmd - The command to send to the cli
4044 returns:
4045 string containing the cli output
4046 None on Error
4047 """
4048 try:
4049 output = self.sendline( cmd )
4050 try:
4051 assert output is not None, "Error in sendline"
4052 # TODO: Maybe make this less hardcoded
4053 # ConsistentMap Exceptions
4054 assert "org.onosproject.store.service" not in output
4055 # Node not leader
4056 assert "java.lang.IllegalStateException" not in output
4057 except AssertionError:
4058 main.log.error( "Error in processing '" + cmd + "' " +
4059 "command: " + str( output ) )
4060 retryTime = 30 # Conservative time, given by Madan
4061 main.log.info( "Waiting " + str( retryTime ) +
4062 "seconds before retrying." )
4063 time.sleep( retryTime ) # Due to change in mastership
4064 output = self.sendline( cmd )
4065 assert output is not None, "Error in sendline"
4066 assert "Command not found:" not in output, output
4067 assert "Error executing command" not in output, output
4068 main.log.info( self.name + ": " + output )
4069 return output
4070 except AssertionError:
4071 main.log.exception( "Error in processing '" + cmd + "' command." )
4072 return None
4073 except TypeError:
4074 main.log.exception( self.name + ": Object not as expected" )
4075 return None
4076 except pexpect.EOF:
4077 main.log.error( self.name + ": EOF exception found" )
4078 main.log.error( self.name + ": " + self.handle.before )
4079 main.cleanup()
4080 main.exit()
4081 except Exception:
4082 main.log.exception( self.name + ": Uncaught exception!" )
4083 main.cleanup()
4084 main.exit()
4085
Jon Hall390696c2015-05-05 17:13:41 -07004086 def setTestAdd( self, setName, values ):
4087 """
4088 CLI command to add elements to a distributed set.
4089 Arguments:
4090 setName - The name of the set to add to.
4091 values - The value(s) to add to the set, space seperated.
4092 Example usages:
4093 setTestAdd( "set1", "a b c" )
4094 setTestAdd( "set2", "1" )
4095 returns:
4096 main.TRUE on success OR
4097 main.FALSE if elements were already in the set OR
4098 main.ERROR on error
4099 """
4100 try:
4101 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004102 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004103 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4104 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jon Hall390696c2015-05-05 17:13:41 -07004105 if re.search( positiveMatch, output):
4106 return main.TRUE
4107 elif re.search( negativeMatch, output):
4108 return main.FALSE
4109 else:
4110 main.log.error( self.name + ": setTestAdd did not" +
4111 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004112 main.log.debug( self.name + " actual: " + repr( output ) )
4113 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004114 except TypeError:
4115 main.log.exception( self.name + ": Object not as expected" )
4116 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004117 except Exception:
4118 main.log.exception( self.name + ": Uncaught exception!" )
4119 main.cleanup()
4120 main.exit()
4121
4122 def setTestRemove( self, setName, values, clear=False, retain=False ):
4123 """
4124 CLI command to remove elements from a distributed set.
4125 Required arguments:
4126 setName - The name of the set to remove from.
4127 values - The value(s) to remove from the set, space seperated.
4128 Optional arguments:
4129 clear - Clear all elements from the set
4130 retain - Retain only the given values. (intersection of the
4131 original set and the given set)
4132 returns:
4133 main.TRUE on success OR
4134 main.FALSE if the set was not changed OR
4135 main.ERROR on error
4136 """
4137 try:
4138 cmdStr = "set-test-remove "
4139 if clear:
4140 cmdStr += "-c " + str( setName )
4141 elif retain:
4142 cmdStr += "-r " + str( setName ) + " " + str( values )
4143 else:
4144 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004145 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004146 if clear:
4147 pattern = "Set " + str( setName ) + " cleared"
4148 if re.search( pattern, output ):
4149 return main.TRUE
4150 elif retain:
4151 positivePattern = str( setName ) + " was pruned to contain " +\
4152 "only elements of set \[(.*)\]"
4153 negativePattern = str( setName ) + " was not changed by " +\
4154 "retaining only elements of the set " +\
4155 "\[(.*)\]"
4156 if re.search( positivePattern, output ):
4157 return main.TRUE
4158 elif re.search( negativePattern, output ):
4159 return main.FALSE
4160 else:
4161 positivePattern = "\[(.*)\] was removed from the set " +\
4162 str( setName )
4163 if ( len( values.split() ) == 1 ):
4164 negativePattern = "\[(.*)\] was not in set " +\
4165 str( setName )
4166 else:
4167 negativePattern = "No element of \[(.*)\] was in set " +\
4168 str( setName )
4169 if re.search( positivePattern, output ):
4170 return main.TRUE
4171 elif re.search( negativePattern, output ):
4172 return main.FALSE
4173 main.log.error( self.name + ": setTestRemove did not" +
4174 " match expected output" )
4175 main.log.debug( self.name + " expected: " + pattern )
4176 main.log.debug( self.name + " actual: " + repr( output ) )
4177 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004178 except TypeError:
4179 main.log.exception( self.name + ": Object not as expected" )
4180 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004181 except Exception:
4182 main.log.exception( self.name + ": Uncaught exception!" )
4183 main.cleanup()
4184 main.exit()
4185
4186 def setTestGet( self, setName, values="" ):
4187 """
4188 CLI command to get the elements in a distributed set.
4189 Required arguments:
4190 setName - The name of the set to remove from.
4191 Optional arguments:
4192 values - The value(s) to check if in the set, space seperated.
4193 returns:
4194 main.ERROR on error OR
4195 A list of elements in the set if no optional arguments are
4196 supplied OR
4197 A tuple containing the list then:
4198 main.FALSE if the given values are not in the set OR
4199 main.TRUE if the given values are in the set OR
4200 """
4201 try:
4202 values = str( values ).strip()
4203 setName = str( setName ).strip()
4204 length = len( values.split() )
4205 containsCheck = None
4206 # Patterns to match
4207 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004208 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004209 containsTrue = "Set " + setName + " contains the value " + values
4210 containsFalse = "Set " + setName + " did not contain the value " +\
4211 values
4212 containsAllTrue = "Set " + setName + " contains the the subset " +\
4213 setPattern
4214 containsAllFalse = "Set " + setName + " did not contain the the" +\
4215 " subset " + setPattern
4216
4217 cmdStr = "set-test-get "
4218 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004219 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004220 if length == 0:
4221 match = re.search( pattern, output )
4222 else: # if given values
4223 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004224 patternTrue = pattern + "\r\n" + containsTrue
4225 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004226 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004227 patternTrue = pattern + "\r\n" + containsAllTrue
4228 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004229 matchTrue = re.search( patternTrue, output )
4230 matchFalse = re.search( patternFalse, output )
4231 if matchTrue:
4232 containsCheck = main.TRUE
4233 match = matchTrue
4234 elif matchFalse:
4235 containsCheck = main.FALSE
4236 match = matchFalse
4237 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004238 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004239 "expected output" )
4240 main.log.debug( self.name + " expected: " + pattern )
4241 main.log.debug( self.name + " actual: " + repr( output ) )
4242 match = None
4243 if match:
4244 setMatch = match.group( 1 )
4245 if setMatch == '':
4246 setList = []
4247 else:
4248 setList = setMatch.split( ", " )
4249 if length > 0:
4250 return ( setList, containsCheck )
4251 else:
4252 return setList
4253 else: # no match
4254 main.log.error( self.name + ": setTestGet did not" +
4255 " match expected output" )
4256 main.log.debug( self.name + " expected: " + pattern )
4257 main.log.debug( self.name + " actual: " + repr( output ) )
4258 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004259 except TypeError:
4260 main.log.exception( self.name + ": Object not as expected" )
4261 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004262 except Exception:
4263 main.log.exception( self.name + ": Uncaught exception!" )
4264 main.cleanup()
4265 main.exit()
4266
4267 def setTestSize( self, setName ):
4268 """
4269 CLI command to get the elements in a distributed set.
4270 Required arguments:
4271 setName - The name of the set to remove from.
4272 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004273 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004274 None on error
4275 """
4276 try:
4277 # TODO: Should this check against the number of elements returned
4278 # and then return true/false based on that?
4279 setName = str( setName ).strip()
4280 # Patterns to match
4281 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004282 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004283 setPattern
4284 cmdStr = "set-test-get -s "
4285 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004286 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004287 match = re.search( pattern, output )
4288 if match:
4289 setSize = int( match.group( 1 ) )
4290 setMatch = match.group( 2 )
4291 if len( setMatch.split() ) == setSize:
4292 main.log.info( "The size returned by " + self.name +
4293 " matches the number of elements in " +
4294 "the returned set" )
4295 else:
4296 main.log.error( "The size returned by " + self.name +
4297 " does not match the number of " +
4298 "elements in the returned set." )
4299 return setSize
4300 else: # no match
4301 main.log.error( self.name + ": setTestGet did not" +
4302 " match expected output" )
4303 main.log.debug( self.name + " expected: " + pattern )
4304 main.log.debug( self.name + " actual: " + repr( output ) )
4305 return None
Jon Hall390696c2015-05-05 17:13:41 -07004306 except TypeError:
4307 main.log.exception( self.name + ": Object not as expected" )
4308 return None
Jon Hall390696c2015-05-05 17:13:41 -07004309 except Exception:
4310 main.log.exception( self.name + ": Uncaught exception!" )
4311 main.cleanup()
4312 main.exit()
4313
Jon Hall80daded2015-05-27 16:07:00 -07004314 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004315 """
4316 Command to list the various counters in the system.
4317 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004318 if jsonFormat, a string of the json object returned by the cli
4319 command
4320 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004321 None on error
4322 """
Jon Hall390696c2015-05-05 17:13:41 -07004323 try:
Jon Hall390696c2015-05-05 17:13:41 -07004324 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004325 if jsonFormat:
4326 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004327 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004328 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004329 assert "Command not found:" not in output, output
4330 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004331 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004332 return output
Jon Hall390696c2015-05-05 17:13:41 -07004333 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004334 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004335 return None
Jon Hall390696c2015-05-05 17:13:41 -07004336 except TypeError:
4337 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004338 return None
Jon Hall390696c2015-05-05 17:13:41 -07004339 except pexpect.EOF:
4340 main.log.error( self.name + ": EOF exception found" )
4341 main.log.error( self.name + ": " + self.handle.before )
4342 main.cleanup()
4343 main.exit()
4344 except Exception:
4345 main.log.exception( self.name + ": Uncaught exception!" )
4346 main.cleanup()
4347 main.exit()
4348
Jon Hall935db192016-04-19 00:22:04 -07004349 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004350 """
Jon Halle1a3b752015-07-22 13:02:46 -07004351 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004352 Required arguments:
4353 counter - The name of the counter to increment.
4354 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004355 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004356 returns:
4357 integer value of the counter or
4358 None on Error
4359 """
4360 try:
4361 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004362 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004363 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004364 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004365 if delta != 1:
4366 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004367 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004368 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004369 match = re.search( pattern, output )
4370 if match:
4371 return int( match.group( 1 ) )
4372 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004373 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004374 " match expected output." )
4375 main.log.debug( self.name + " expected: " + pattern )
4376 main.log.debug( self.name + " actual: " + repr( output ) )
4377 return None
Jon Hall390696c2015-05-05 17:13:41 -07004378 except TypeError:
4379 main.log.exception( self.name + ": Object not as expected" )
4380 return None
Jon Hall390696c2015-05-05 17:13:41 -07004381 except Exception:
4382 main.log.exception( self.name + ": Uncaught exception!" )
4383 main.cleanup()
4384 main.exit()
4385
Jon Hall935db192016-04-19 00:22:04 -07004386 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004387 """
4388 CLI command to get a distributed counter then add a delta to it.
4389 Required arguments:
4390 counter - The name of the counter to increment.
4391 Optional arguments:
4392 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004393 returns:
4394 integer value of the counter or
4395 None on Error
4396 """
4397 try:
4398 counter = str( counter )
4399 delta = int( delta )
4400 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004401 cmdStr += counter
4402 if delta != 1:
4403 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004404 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004405 pattern = counter + " was updated to (-?\d+)"
4406 match = re.search( pattern, output )
4407 if match:
4408 return int( match.group( 1 ) )
4409 else:
4410 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4411 " match expected output." )
4412 main.log.debug( self.name + " expected: " + pattern )
4413 main.log.debug( self.name + " actual: " + repr( output ) )
4414 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004415 except TypeError:
4416 main.log.exception( self.name + ": Object not as expected" )
4417 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004418 except Exception:
4419 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle1a3b752015-07-22 13:02:46 -07004420 main.cleanup()
4421 main.exit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004422
4423 def valueTestGet( self, valueName ):
4424 """
4425 CLI command to get the value of an atomic value.
4426 Required arguments:
4427 valueName - The name of the value to get.
4428 returns:
4429 string value of the value or
4430 None on Error
4431 """
4432 try:
4433 valueName = str( valueName )
4434 cmdStr = "value-test "
4435 operation = "get"
4436 cmdStr = "value-test {} {}".format( valueName,
4437 operation )
4438 output = self.distPrimitivesSend( cmdStr )
4439 pattern = "(\w+)"
4440 match = re.search( pattern, output )
4441 if match:
4442 return match.group( 1 )
4443 else:
4444 main.log.error( self.name + ": valueTestGet did not" +
4445 " match expected output." )
4446 main.log.debug( self.name + " expected: " + pattern )
4447 main.log.debug( self.name + " actual: " + repr( output ) )
4448 return None
4449 except TypeError:
4450 main.log.exception( self.name + ": Object not as expected" )
4451 return None
4452 except Exception:
4453 main.log.exception( self.name + ": Uncaught exception!" )
4454 main.cleanup()
4455 main.exit()
4456
4457 def valueTestSet( self, valueName, newValue ):
4458 """
4459 CLI command to set the value of an atomic value.
4460 Required arguments:
4461 valueName - The name of the value to set.
4462 newValue - The value to assign to the given value.
4463 returns:
4464 main.TRUE on success or
4465 main.ERROR on Error
4466 """
4467 try:
4468 valueName = str( valueName )
4469 newValue = str( newValue )
4470 operation = "set"
4471 cmdStr = "value-test {} {} {}".format( valueName,
4472 operation,
4473 newValue )
4474 output = self.distPrimitivesSend( cmdStr )
4475 if output is not None:
4476 return main.TRUE
4477 else:
4478 return main.ERROR
4479 except TypeError:
4480 main.log.exception( self.name + ": Object not as expected" )
4481 return main.ERROR
4482 except Exception:
4483 main.log.exception( self.name + ": Uncaught exception!" )
4484 main.cleanup()
4485 main.exit()
4486
4487 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4488 """
4489 CLI command to compareAndSet the value of an atomic value.
4490 Required arguments:
4491 valueName - The name of the value.
4492 oldValue - Compare the current value of the atomic value to this
4493 newValue - If the value equals oldValue, set the value to newValue
4494 returns:
4495 main.TRUE on success or
4496 main.FALSE on failure or
4497 main.ERROR on Error
4498 """
4499 try:
4500 valueName = str( valueName )
4501 oldValue = str( oldValue )
4502 newValue = str( newValue )
4503 operation = "compareAndSet"
4504 cmdStr = "value-test {} {} {} {}".format( valueName,
4505 operation,
4506 oldValue,
4507 newValue )
4508 output = self.distPrimitivesSend( cmdStr )
4509 pattern = "(\w+)"
4510 match = re.search( pattern, output )
4511 if match:
4512 result = match.group( 1 )
4513 if result == "true":
4514 return main.TRUE
4515 elif result == "false":
4516 return main.FALSE
4517 else:
4518 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4519 " match expected output." )
4520 main.log.debug( self.name + " expected: " + pattern )
4521 main.log.debug( self.name + " actual: " + repr( output ) )
4522 return main.ERROR
4523 except TypeError:
4524 main.log.exception( self.name + ": Object not as expected" )
4525 return main.ERROR
4526 except Exception:
4527 main.log.exception( self.name + ": Uncaught exception!" )
4528 main.cleanup()
4529 main.exit()
4530
4531 def valueTestGetAndSet( self, valueName, newValue ):
4532 """
4533 CLI command to getAndSet the value of an atomic value.
4534 Required arguments:
4535 valueName - The name of the value to get.
4536 newValue - The value to assign to the given value
4537 returns:
4538 string value of the value or
4539 None on Error
4540 """
4541 try:
4542 valueName = str( valueName )
4543 cmdStr = "value-test "
4544 operation = "getAndSet"
4545 cmdStr += valueName + " " + operation
4546 cmdStr = "value-test {} {} {}".format( valueName,
4547 operation,
4548 newValue )
4549 output = self.distPrimitivesSend( cmdStr )
4550 pattern = "(\w+)"
4551 match = re.search( pattern, output )
4552 if match:
4553 return match.group( 1 )
4554 else:
4555 main.log.error( self.name + ": valueTestGetAndSet did not" +
4556 " match expected output." )
4557 main.log.debug( self.name + " expected: " + pattern )
4558 main.log.debug( self.name + " actual: " + repr( output ) )
4559 return None
4560 except TypeError:
4561 main.log.exception( self.name + ": Object not as expected" )
4562 return None
4563 except Exception:
4564 main.log.exception( self.name + ": Uncaught exception!" )
4565 main.cleanup()
4566 main.exit()
4567
4568 def valueTestDestroy( self, valueName ):
4569 """
4570 CLI command to destroy an atomic value.
4571 Required arguments:
4572 valueName - The name of the value to destroy.
4573 returns:
4574 main.TRUE on success or
4575 main.ERROR on Error
4576 """
4577 try:
4578 valueName = str( valueName )
4579 cmdStr = "value-test "
4580 operation = "destroy"
4581 cmdStr += valueName + " " + operation
4582 output = self.distPrimitivesSend( cmdStr )
4583 if output is not None:
4584 return main.TRUE
4585 else:
4586 return main.ERROR
4587 except TypeError:
4588 main.log.exception( self.name + ": Object not as expected" )
4589 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004590 except Exception:
4591 main.log.exception( self.name + ": Uncaught exception!" )
4592 main.cleanup()
4593 main.exit()
4594
YPZhangfebf7302016-05-24 16:45:56 -07004595 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004596 """
4597 Description: Execute summary command in onos
4598 Returns: json object ( summary -j ), returns main.FALSE if there is
4599 no output
4600
4601 """
4602 try:
4603 cmdStr = "summary"
4604 if jsonFormat:
4605 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004606 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004607 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004608 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004609 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004610 if not handle:
4611 main.log.error( self.name + ": There is no output in " +
4612 "summary command" )
4613 return main.FALSE
4614 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004615 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004616 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004617 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004618 except TypeError:
4619 main.log.exception( self.name + ": Object not as expected" )
4620 return None
4621 except pexpect.EOF:
4622 main.log.error( self.name + ": EOF exception found" )
4623 main.log.error( self.name + ": " + self.handle.before )
4624 main.cleanup()
4625 main.exit()
4626 except Exception:
4627 main.log.exception( self.name + ": Uncaught exception!" )
4628 main.cleanup()
4629 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004630
Jon Hall935db192016-04-19 00:22:04 -07004631 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004632 """
4633 CLI command to get the value of a key in a consistent map using
4634 transactions. This a test function and can only get keys from the
4635 test map hard coded into the cli command
4636 Required arguments:
4637 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004638 returns:
4639 The string value of the key or
4640 None on Error
4641 """
4642 try:
4643 keyName = str( keyName )
4644 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004645 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004646 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004647 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4648 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004649 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004650 return None
4651 else:
4652 match = re.search( pattern, output )
4653 if match:
4654 return match.groupdict()[ 'value' ]
4655 else:
4656 main.log.error( self.name + ": transactionlMapGet did not" +
4657 " match expected output." )
4658 main.log.debug( self.name + " expected: " + pattern )
4659 main.log.debug( self.name + " actual: " + repr( output ) )
4660 return None
4661 except TypeError:
4662 main.log.exception( self.name + ": Object not as expected" )
4663 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004664 except Exception:
4665 main.log.exception( self.name + ": Uncaught exception!" )
4666 main.cleanup()
4667 main.exit()
4668
Jon Hall935db192016-04-19 00:22:04 -07004669 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004670 """
4671 CLI command to put a value into 'numKeys' number of keys in a
4672 consistent map using transactions. This a test function and can only
4673 put into keys named 'Key#' of the test map hard coded into the cli command
4674 Required arguments:
4675 numKeys - Number of keys to add the value to
4676 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004677 returns:
4678 A dictionary whose keys are the name of the keys put into the map
4679 and the values of the keys are dictionaries whose key-values are
4680 'value': value put into map and optionaly
4681 'oldValue': Previous value in the key or
4682 None on Error
4683
4684 Example output
4685 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4686 'Key2': {'value': 'Testing'} }
4687 """
4688 try:
4689 numKeys = str( numKeys )
4690 value = str( value )
4691 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004692 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004693 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004694 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4695 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4696 results = {}
4697 for line in output.splitlines():
4698 new = re.search( newPattern, line )
4699 updated = re.search( updatedPattern, line )
4700 if new:
4701 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4702 elif updated:
4703 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004704 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004705 else:
4706 main.log.error( self.name + ": transactionlMapGet did not" +
4707 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004708 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4709 newPattern,
4710 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004711 main.log.debug( self.name + " actual: " + repr( output ) )
4712 return results
4713 except TypeError:
4714 main.log.exception( self.name + ": Object not as expected" )
4715 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004716 except Exception:
4717 main.log.exception( self.name + ": Uncaught exception!" )
4718 main.cleanup()
4719 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004720
acsmarsdaea66c2015-09-03 11:44:06 -07004721 def maps( self, jsonFormat=True ):
4722 """
4723 Description: Returns result of onos:maps
4724 Optional:
4725 * jsonFormat: enable json formatting of output
4726 """
4727 try:
4728 cmdStr = "maps"
4729 if jsonFormat:
4730 cmdStr += " -j"
4731 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004732 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004733 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004734 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004735 except AssertionError:
4736 main.log.exception( "" )
4737 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004738 except TypeError:
4739 main.log.exception( self.name + ": Object not as expected" )
4740 return None
4741 except pexpect.EOF:
4742 main.log.error( self.name + ": EOF exception found" )
4743 main.log.error( self.name + ": " + self.handle.before )
4744 main.cleanup()
4745 main.exit()
4746 except Exception:
4747 main.log.exception( self.name + ": Uncaught exception!" )
4748 main.cleanup()
4749 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004750
4751 def getSwController( self, uri, jsonFormat=True ):
4752 """
4753 Descrition: Gets the controller information from the device
4754 """
4755 try:
4756 cmd = "device-controllers "
4757 if jsonFormat:
4758 cmd += "-j "
4759 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004760 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004761 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004762 return response
Jon Hallc6793552016-01-19 14:18:37 -08004763 except AssertionError:
4764 main.log.exception( "" )
4765 return None
GlennRC050596c2015-11-18 17:06:41 -08004766 except TypeError:
4767 main.log.exception( self.name + ": Object not as expected" )
4768 return None
4769 except pexpect.EOF:
4770 main.log.error( self.name + ": EOF exception found" )
4771 main.log.error( self.name + ": " + self.handle.before )
4772 main.cleanup()
4773 main.exit()
4774 except Exception:
4775 main.log.exception( self.name + ": Uncaught exception!" )
4776 main.cleanup()
4777 main.exit()
4778
4779 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4780 """
4781 Descrition: sets the controller(s) for the specified device
4782
4783 Parameters:
4784 Required: uri - String: The uri of the device(switch).
4785 ip - String or List: The ip address of the controller.
4786 This parameter can be formed in a couple of different ways.
4787 VALID:
4788 10.0.0.1 - just the ip address
4789 tcp:10.0.0.1 - the protocol and the ip address
4790 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4791 so that you can add controllers with different
4792 protocols and ports
4793 INVALID:
4794 10.0.0.1:6653 - this is not supported by ONOS
4795
4796 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4797 port - The port number.
4798 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4799
4800 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4801 """
4802 try:
4803 cmd = "device-setcontrollers"
4804
4805 if jsonFormat:
4806 cmd += " -j"
4807 cmd += " " + uri
4808 if isinstance( ip, str ):
4809 ip = [ip]
4810 for item in ip:
4811 if ":" in item:
4812 sitem = item.split( ":" )
4813 if len(sitem) == 3:
4814 cmd += " " + item
4815 elif "." in sitem[1]:
4816 cmd += " {}:{}".format(item, port)
4817 else:
4818 main.log.error( "Malformed entry: " + item )
4819 raise TypeError
4820 else:
4821 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004822 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004823 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004824 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004825 if "Error" in response:
4826 main.log.error( response )
4827 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004828 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004829 except AssertionError:
4830 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004831 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004832 except TypeError:
4833 main.log.exception( self.name + ": Object not as expected" )
4834 return main.FALSE
4835 except pexpect.EOF:
4836 main.log.error( self.name + ": EOF exception found" )
4837 main.log.error( self.name + ": " + self.handle.before )
4838 main.cleanup()
4839 main.exit()
4840 except Exception:
4841 main.log.exception( self.name + ": Uncaught exception!" )
4842 main.cleanup()
4843 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004844
4845 def removeDevice( self, device ):
4846 '''
4847 Description:
4848 Remove a device from ONOS by passing the uri of the device(s).
4849 Parameters:
4850 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4851 Returns:
4852 Returns main.FALSE if an exception is thrown or an error is present
4853 in the response. Otherwise, returns main.TRUE.
4854 NOTE:
4855 If a host cannot be removed, then this function will return main.FALSE
4856 '''
4857 try:
4858 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004859 deviceStr = device
4860 device = []
4861 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004862
4863 for d in device:
4864 time.sleep( 1 )
4865 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004866 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004867 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004868 if "Error" in response:
4869 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4870 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004871 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004872 except AssertionError:
4873 main.log.exception( "" )
4874 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004875 except TypeError:
4876 main.log.exception( self.name + ": Object not as expected" )
4877 return main.FALSE
4878 except pexpect.EOF:
4879 main.log.error( self.name + ": EOF exception found" )
4880 main.log.error( self.name + ": " + self.handle.before )
4881 main.cleanup()
4882 main.exit()
4883 except Exception:
4884 main.log.exception( self.name + ": Uncaught exception!" )
4885 main.cleanup()
4886 main.exit()
4887
4888 def removeHost( self, host ):
4889 '''
4890 Description:
4891 Remove a host from ONOS by passing the id of the host(s)
4892 Parameters:
4893 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4894 Returns:
4895 Returns main.FALSE if an exception is thrown or an error is present
4896 in the response. Otherwise, returns main.TRUE.
4897 NOTE:
4898 If a host cannot be removed, then this function will return main.FALSE
4899 '''
4900 try:
4901 if type( host ) is str:
4902 host = list( host )
4903
4904 for h in host:
4905 time.sleep( 1 )
4906 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004907 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004908 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004909 if "Error" in response:
4910 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4911 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004912 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004913 except AssertionError:
4914 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004915 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004916 except TypeError:
4917 main.log.exception( self.name + ": Object not as expected" )
4918 return main.FALSE
4919 except pexpect.EOF:
4920 main.log.error( self.name + ": EOF exception found" )
4921 main.log.error( self.name + ": " + self.handle.before )
4922 main.cleanup()
4923 main.exit()
4924 except Exception:
4925 main.log.exception( self.name + ": Uncaught exception!" )
4926 main.cleanup()
4927 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004928
YPZhangfebf7302016-05-24 16:45:56 -07004929 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004930 '''
4931 Description:
4932 Bring link down or up in the null-provider.
4933 params:
4934 begin - (string) One end of a device or switch.
4935 end - (string) the other end of the device or switch
4936 returns:
4937 main.TRUE if no exceptions were thrown and no Errors are
4938 present in the resoponse. Otherwise, returns main.FALSE
4939 '''
4940 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004941 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004942 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004943 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004944 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004945 if "Error" in response or "Failure" in response:
4946 main.log.error( response )
4947 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004948 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004949 except AssertionError:
4950 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004951 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004952 except TypeError:
4953 main.log.exception( self.name + ": Object not as expected" )
4954 return main.FALSE
4955 except pexpect.EOF:
4956 main.log.error( self.name + ": EOF exception found" )
4957 main.log.error( self.name + ": " + self.handle.before )
4958 main.cleanup()
4959 main.exit()
4960 except Exception:
4961 main.log.exception( self.name + ": Uncaught exception!" )
4962 main.cleanup()
4963 main.exit()
4964
Jon Hall2c8959e2016-12-16 12:17:34 -08004965 def portstate( self, dpid, port, state ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07004966 '''
4967 Description:
4968 Changes the state of port in an OF switch by means of the
4969 PORTSTATUS OF messages.
4970 params:
Jon Hall2c8959e2016-12-16 12:17:34 -08004971 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
4972 port - (string) target port in the device. Ex: '2'
4973 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07004974 returns:
4975 main.TRUE if no exceptions were thrown and no Errors are
4976 present in the resoponse. Otherwise, returns main.FALSE
4977 '''
4978 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08004979 state = state.lower()
4980 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07004981 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004982 response = self.sendline( cmd, showResponse=True )
4983 assert response is not None, "Error in sendline"
4984 assert "Command not found:" not in response, response
4985 if "Error" in response or "Failure" in response:
4986 main.log.error( response )
4987 return main.FALSE
4988 return main.TRUE
4989 except AssertionError:
4990 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004991 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07004992 except TypeError:
4993 main.log.exception( self.name + ": Object not as expected" )
4994 return main.FALSE
4995 except pexpect.EOF:
4996 main.log.error( self.name + ": EOF exception found" )
4997 main.log.error( self.name + ": " + self.handle.before )
4998 main.cleanup()
4999 main.exit()
5000 except Exception:
5001 main.log.exception( self.name + ": Uncaught exception!" )
5002 main.cleanup()
5003 main.exit()
5004
5005 def logSet( self, level="INFO", app="org.onosproject" ):
5006 """
5007 Set the logging level to lvl for a specific app
5008 returns main.TRUE on success
5009 returns main.FALSE if Error occurred
5010 if noExit is True, TestON will not exit, but clean up
5011 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5012 Level defaults to INFO
5013 """
5014 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005015 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005016 self.handle.expect( "onos>" )
5017
5018 response = self.handle.before
5019 if re.search( "Error", response ):
5020 return main.FALSE
5021 return main.TRUE
5022 except pexpect.TIMEOUT:
5023 main.log.exception( self.name + ": TIMEOUT exception found" )
5024 main.cleanup()
5025 main.exit()
5026 except pexpect.EOF:
5027 main.log.error( self.name + ": EOF exception found" )
5028 main.log.error( self.name + ": " + self.handle.before )
5029 main.cleanup()
5030 main.exit()
5031 except Exception:
5032 main.log.exception( self.name + ": Uncaught exception!" )
5033 main.cleanup()
5034 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005035
5036 def getGraphDict( self, timeout=60, includeHost=False ):
5037 """
5038 Return a dictionary which describes the latest network topology data as a
5039 graph.
5040 An example of the dictionary:
5041 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5042 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5043 Each vertex should at least have an 'edges' attribute which describes the
5044 adjacency information. The value of 'edges' attribute is also represented by
5045 a dictionary, which maps each edge (identified by the neighbor vertex) to a
5046 list of attributes.
5047 An example of the edges dictionary:
5048 'edges': { vertex2: { 'port': ..., 'weight': ... },
5049 vertex3: { 'port': ..., 'weight': ... } }
5050 If includeHost == True, all hosts (and host-switch links) will be included
5051 in topology data.
5052 """
5053 graphDict = {}
5054 try:
5055 links = self.links()
5056 links = json.loads( links )
5057 devices = self.devices()
5058 devices = json.loads( devices )
5059 idToDevice = {}
5060 for device in devices:
5061 idToDevice[ device[ 'id' ] ] = device
5062 if includeHost:
5063 hosts = self.hosts()
5064 # FIXME: support 'includeHost' argument
5065 for link in links:
5066 nodeA = link[ 'src' ][ 'device' ]
5067 nodeB = link[ 'dst' ][ 'device' ]
5068 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005069 if nodeA not in graphDict.keys():
5070 graphDict[ nodeA ] = { 'edges': {},
5071 'dpid': idToDevice[ nodeA ][ 'id' ][3:],
5072 'type': idToDevice[ nodeA ][ 'type' ],
5073 'available': idToDevice[ nodeA ][ 'available' ],
5074 'role': idToDevice[ nodeA ][ 'role' ],
5075 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5076 'hw': idToDevice[ nodeA ][ 'hw' ],
5077 'sw': idToDevice[ nodeA ][ 'sw' ],
5078 'serial': idToDevice[ nodeA ][ 'serial' ],
5079 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
5080 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005081 else:
5082 # Assert nodeB is not connected to any current links of nodeA
5083 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005084 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5085 'type': link[ 'type' ],
5086 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005087 return graphDict
5088 except ( TypeError, ValueError ):
5089 main.log.exception( self.name + ": Object not as expected" )
5090 return None
5091 except KeyError:
5092 main.log.exception( self.name + ": KeyError exception found" )
5093 return None
5094 except AssertionError:
5095 main.log.exception( self.name + ": AssertionError exception found" )
5096 return None
5097 except pexpect.EOF:
5098 main.log.error( self.name + ": EOF exception found" )
5099 main.log.error( self.name + ": " + self.handle.before )
5100 return None
5101 except Exception:
5102 main.log.exception( self.name + ": Uncaught exception!" )
5103 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005104
5105 def getIntentPerfSummary( self ):
5106 '''
5107 Send command to check intent-perf summary
5108 Returns: dictionary for intent-perf summary
5109 if something wrong, function will return None
5110 '''
5111 cmd = "intent-perf -s"
5112 respDic = {}
5113 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005114 assert resp is not None, "Error in sendline"
5115 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005116 try:
5117 # Generate the dictionary to return
5118 for l in resp.split( "\n" ):
5119 # Delete any white space in line
5120 temp = re.sub( r'\s+', '', l )
5121 temp = temp.split( ":" )
5122 respDic[ temp[0] ] = temp[ 1 ]
5123
5124 except (TypeError, ValueError):
5125 main.log.exception( self.name + ": Object not as expected" )
5126 return None
5127 except KeyError:
5128 main.log.exception( self.name + ": KeyError exception found" )
5129 return None
5130 except AssertionError:
5131 main.log.exception( self.name + ": AssertionError exception found" )
5132 return None
5133 except pexpect.EOF:
5134 main.log.error( self.name + ": EOF exception found" )
5135 main.log.error( self.name + ": " + self.handle.before )
5136 return None
5137 except Exception:
5138 main.log.exception( self.name + ": Uncaught exception!" )
5139 return None
5140 return respDic
5141
Chiyu Chengec63bde2016-11-17 18:11:36 -08005142 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005143 """
5144 Searches the latest ONOS log file for the given search term and
5145 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005146
chengchiyu08303a02016-09-08 17:40:26 -07005147 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005148 searchTerm:
5149 The string to grep from the ONOS log.
5150 startLine:
5151 The term that decides which line is the start to search the searchTerm in
5152 the karaf log. For now, startTerm only works in 'first' mode.
5153 logNum:
5154 In some extreme cases, one karaf log is not big enough to contain all the
5155 information.Because of this, search mutiply logs is necessary to capture
5156 the right result. logNum is the number of karaf logs that we need to search
5157 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005158 mode:
5159 all: return all the strings that contain the search term
5160 last: return the last string that contains the search term
5161 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005162 num: return the number of times that the searchTerm appears in the log
5163 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005164 """
5165 try:
5166 assert type( searchTerm ) is str
Jon Halle0f0b342017-04-18 11:43:47 -07005167 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005168 logPath = '/opt/onos/log/karaf.log.'
5169 logPaths = '/opt/onos/log/karaf.log'
5170 for i in range( 1, logNum ):
5171 logPaths = logPath + str( i ) + " " + logPaths
5172 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005173 if startLine:
5174 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5175 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005176 if mode == 'all':
5177 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005178 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005179 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005180 elif mode == 'first':
5181 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5182 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005183 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005184 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005185 return num
You Wang6d301d42017-04-21 10:49:33 -07005186 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005187 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
5188 return int(totalLines)
You Wang6d301d42017-04-21 10:49:33 -07005189 else:
5190 main.log.error( self.name + " unsupported mode" )
5191 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005192 before = self.sendline( cmd )
5193 before = before.splitlines()
5194 # make sure the returned list only contains the search term
5195 returnLines = [line for line in before if searchTerm in line]
5196 return returnLines
5197 except AssertionError:
5198 main.log.error( self.name + " searchTerm is not string type" )
5199 return None
5200 except pexpect.EOF:
5201 main.log.error( self.name + ": EOF exception found" )
5202 main.log.error( self.name + ": " + self.handle.before )
5203 main.cleanup()
5204 main.exit()
5205 except pexpect.TIMEOUT:
5206 main.log.error( self.name + ": TIMEOUT exception found" )
5207 main.log.error( self.name + ": " + self.handle.before )
5208 main.cleanup()
5209 main.exit()
5210 except Exception:
5211 main.log.exception( self.name + ": Uncaught exception!" )
5212 main.cleanup()
5213 main.exit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005214
5215 def vplsShow( self, jsonFormat=True ):
5216 """
5217 Description: Returns result of onos:vpls show, which should list the
5218 configured VPLS networks and the assigned interfaces.
5219 Optional:
5220 * jsonFormat: enable json formatting of output
5221 Returns:
5222 The output of the command or None on error.
5223 """
5224 try:
5225 cmdStr = "vpls show"
5226 if jsonFormat:
5227 raise NotImplementedError
5228 cmdStr += " -j"
5229 handle = self.sendline( cmdStr )
5230 assert handle is not None, "Error in sendline"
5231 assert "Command not found:" not in handle, handle
5232 return handle
5233 except AssertionError:
5234 main.log.exception( "" )
5235 return None
5236 except TypeError:
5237 main.log.exception( self.name + ": Object not as expected" )
5238 return None
5239 except pexpect.EOF:
5240 main.log.error( self.name + ": EOF exception found" )
5241 main.log.error( self.name + ": " + self.handle.before )
5242 main.cleanup()
5243 main.exit()
5244 except NotImplementedError:
5245 main.log.exception( self.name + ": Json output not supported")
5246 return None
5247 except Exception:
5248 main.log.exception( self.name + ": Uncaught exception!" )
5249 main.cleanup()
5250 main.exit()
5251
5252 def parseVplsShow( self ):
5253 """
5254 Parse the cli output of 'vpls show' into json output. This is required
5255 as there is currently no json output available.
5256 """
5257 try:
5258 output = []
5259 raw = self.vplsShow( jsonFormat=False )
5260 namePat = "VPLS name: (?P<name>\w+)"
5261 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5262 encapPat = "Encapsulation: (?P<encap>\w+)"
5263 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5264 mIter = re.finditer( pattern, raw )
5265 for match in mIter:
5266 item = {}
5267 item[ 'name' ] = match.group( 'name' )
5268 ifaces = match.group( 'interfaces' ).split( ', ')
5269 if ifaces == [ "" ]:
5270 ifaces = []
5271 item[ 'interfaces' ] = ifaces
5272 encap = match.group( 'encap' )
5273 if encap != 'NONE':
5274 item[ 'encapsulation' ] = encap.lower()
5275 output.append( item )
5276 return output
5277 except Exception:
5278 main.log.exception( self.name + ": Uncaught exception!" )
5279 main.cleanup()
5280 main.exit()
5281
5282 def vplsList( self, jsonFormat=True ):
5283 """
5284 Description: Returns result of onos:vpls list, which should list the
5285 configured VPLS networks.
5286 Optional:
5287 * jsonFormat: enable json formatting of output
5288 """
5289 try:
5290 cmdStr = "vpls list"
5291 if jsonFormat:
5292 raise NotImplementedError
5293 cmdStr += " -j"
5294 handle = self.sendline( cmdStr )
5295 assert handle is not None, "Error in sendline"
5296 assert "Command not found:" not in handle, handle
5297 return handle
5298 except AssertionError:
5299 main.log.exception( "" )
5300 return None
5301 except TypeError:
5302 main.log.exception( self.name + ": Object not as expected" )
5303 return None
5304 except pexpect.EOF:
5305 main.log.error( self.name + ": EOF exception found" )
5306 main.log.error( self.name + ": " + self.handle.before )
5307 main.cleanup()
5308 main.exit()
5309 except NotImplementedError:
5310 main.log.exception( self.name + ": Json output not supported")
5311 return None
5312 except Exception:
5313 main.log.exception( self.name + ": Uncaught exception!" )
5314 main.cleanup()
5315 main.exit()
5316
5317 def vplsCreate( self, network ):
5318 """
5319 CLI command to create a new VPLS network.
5320 Required arguments:
5321 network - String name of the network to create.
5322 returns:
5323 main.TRUE on success and main.FALSE on failure
5324 """
5325 try:
5326 network = str( network )
5327 cmdStr = "vpls create "
5328 cmdStr += network
5329 output = self.sendline( cmdStr )
5330 assert output is not None, "Error in sendline"
5331 assert "Command not found:" not in output, output
5332 assert "Error executing command" not in output, output
5333 assert "VPLS already exists:" not in output, output
5334 return main.TRUE
5335 except AssertionError:
5336 main.log.exception( "" )
5337 return main.FALSE
5338 except TypeError:
5339 main.log.exception( self.name + ": Object not as expected" )
5340 return main.FALSE
5341 except pexpect.EOF:
5342 main.log.error( self.name + ": EOF exception found" )
5343 main.log.error( self.name + ": " + self.handle.before )
5344 main.cleanup()
5345 main.exit()
5346 except Exception:
5347 main.log.exception( self.name + ": Uncaught exception!" )
5348 main.cleanup()
5349 main.exit()
5350
5351 def vplsDelete( self, network ):
5352 """
5353 CLI command to delete a VPLS network.
5354 Required arguments:
5355 network - Name of the network to delete.
5356 returns:
5357 main.TRUE on success and main.FALSE on failure
5358 """
5359 try:
5360 network = str( network )
5361 cmdStr = "vpls delete "
5362 cmdStr += network
5363 output = self.sendline( cmdStr )
5364 assert output is not None, "Error in sendline"
5365 assert "Command not found:" not in output, output
5366 assert "Error executing command" not in output, output
5367 assert " not found" not in output, output
5368 return main.TRUE
5369 except AssertionError:
5370 main.log.exception( "" )
5371 return main.FALSE
5372 except TypeError:
5373 main.log.exception( self.name + ": Object not as expected" )
5374 return main.FALSE
5375 except pexpect.EOF:
5376 main.log.error( self.name + ": EOF exception found" )
5377 main.log.error( self.name + ": " + self.handle.before )
5378 main.cleanup()
5379 main.exit()
5380 except Exception:
5381 main.log.exception( self.name + ": Uncaught exception!" )
5382 main.cleanup()
5383 main.exit()
5384
5385 def vplsAddIface( self, network, iface ):
5386 """
5387 CLI command to add an interface to a VPLS network.
5388 Required arguments:
5389 network - Name of the network to add the interface to.
5390 iface - The ONOS name for an interface.
5391 returns:
5392 main.TRUE on success and main.FALSE on failure
5393 """
5394 try:
5395 network = str( network )
5396 iface = str( iface )
5397 cmdStr = "vpls add-if "
5398 cmdStr += network + " " + iface
5399 output = self.sendline( cmdStr )
5400 assert output is not None, "Error in sendline"
5401 assert "Command not found:" not in output, output
5402 assert "Error executing command" not in output, output
5403 assert "already associated to network" not in output, output
5404 assert "Interface cannot be added." not in output, output
5405 return main.TRUE
5406 except AssertionError:
5407 main.log.exception( "" )
5408 return main.FALSE
5409 except TypeError:
5410 main.log.exception( self.name + ": Object not as expected" )
5411 return main.FALSE
5412 except pexpect.EOF:
5413 main.log.error( self.name + ": EOF exception found" )
5414 main.log.error( self.name + ": " + self.handle.before )
5415 main.cleanup()
5416 main.exit()
5417 except Exception:
5418 main.log.exception( self.name + ": Uncaught exception!" )
5419 main.cleanup()
5420 main.exit()
5421
5422 def vplsRemIface( self, network, iface ):
5423 """
5424 CLI command to remove an interface from a VPLS network.
5425 Required arguments:
5426 network - Name of the network to remove the interface from.
5427 iface - Name of the interface to remove.
5428 returns:
5429 main.TRUE on success and main.FALSE on failure
5430 """
5431 try:
5432 iface = str( iface )
5433 cmdStr = "vpls rem-if "
5434 cmdStr += network + " " + iface
5435 output = self.sendline( cmdStr )
5436 assert output is not None, "Error in sendline"
5437 assert "Command not found:" not in output, output
5438 assert "Error executing command" not in output, output
5439 assert "is not configured" not in output, output
5440 return main.TRUE
5441 except AssertionError:
5442 main.log.exception( "" )
5443 return main.FALSE
5444 except TypeError:
5445 main.log.exception( self.name + ": Object not as expected" )
5446 return main.FALSE
5447 except pexpect.EOF:
5448 main.log.error( self.name + ": EOF exception found" )
5449 main.log.error( self.name + ": " + self.handle.before )
5450 main.cleanup()
5451 main.exit()
5452 except Exception:
5453 main.log.exception( self.name + ": Uncaught exception!" )
5454 main.cleanup()
5455 main.exit()
5456
5457 def vplsClean( self ):
5458 """
5459 Description: Clears the VPLS app configuration.
5460 Returns: main.TRUE on success and main.FALSE on failure
5461 """
5462 try:
5463 cmdStr = "vpls clean"
5464 handle = self.sendline( cmdStr )
5465 assert handle is not None, "Error in sendline"
5466 assert "Command not found:" not in handle, handle
5467 return handle
5468 except AssertionError:
5469 main.log.exception( "" )
5470 return main.FALSE
5471 except TypeError:
5472 main.log.exception( self.name + ": Object not as expected" )
5473 return main.FALSE
5474 except pexpect.EOF:
5475 main.log.error( self.name + ": EOF exception found" )
5476 main.log.error( self.name + ": " + self.handle.before )
5477 main.cleanup()
5478 main.exit()
5479 except Exception:
5480 main.log.exception( self.name + ": Uncaught exception!" )
5481 main.cleanup()
5482 main.exit()
5483
5484 def vplsSetEncap( self, network, encapType ):
5485 """
5486 CLI command to add an interface to a VPLS network.
5487 Required arguments:
5488 network - Name of the network to create.
5489 encapType - Type of encapsulation.
5490 returns:
5491 main.TRUE on success and main.FALSE on failure
5492 """
5493 try:
5494 network = str( network )
5495 encapType = str( encapType ).upper()
5496 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5497 cmdStr = "vpls set-encap "
5498 cmdStr += network + " " + encapType
5499 output = self.sendline( cmdStr )
5500 assert output is not None, "Error in sendline"
5501 assert "Command not found:" not in output, output
5502 assert "Error executing command" not in output, output
5503 assert "already associated to network" not in output, output
5504 assert "Encapsulation type " not in output, output
5505 return main.TRUE
5506 except AssertionError:
5507 main.log.exception( "" )
5508 return main.FALSE
5509 except TypeError:
5510 main.log.exception( self.name + ": Object not as expected" )
5511 return main.FALSE
5512 except pexpect.EOF:
5513 main.log.error( self.name + ": EOF exception found" )
5514 main.log.error( self.name + ": " + self.handle.before )
5515 main.cleanup()
5516 main.exit()
5517 except Exception:
5518 main.log.exception( self.name + ": Uncaught exception!" )
5519 main.cleanup()
5520 main.exit()
5521
5522 def interfaces( self, jsonFormat=True ):
5523 """
5524 Description: Returns result of interfaces command.
5525 Optional:
5526 * jsonFormat: enable json formatting of output
5527 Returns:
5528 The output of the command or None on error.
5529 """
5530 try:
5531 cmdStr = "interfaces"
5532 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005533 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005534 cmdStr += " -j"
5535 handle = self.sendline( cmdStr )
5536 assert handle is not None, "Error in sendline"
5537 assert "Command not found:" not in handle, handle
5538 return handle
5539 except AssertionError:
5540 main.log.exception( "" )
5541 return None
5542 except TypeError:
5543 main.log.exception( self.name + ": Object not as expected" )
5544 return None
5545 except pexpect.EOF:
5546 main.log.error( self.name + ": EOF exception found" )
5547 main.log.error( self.name + ": " + self.handle.before )
5548 main.cleanup()
5549 main.exit()
5550 except NotImplementedError:
5551 main.log.exception( self.name + ": Json output not supported")
5552 return None
5553 except Exception:
5554 main.log.exception( self.name + ": Uncaught exception!" )
5555 main.cleanup()
5556 main.exit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005557
5558 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
5559 '''
5560 Get the timestamp of searchTerm from karaf log.
5561
5562 Arguments:
5563 splitTerm_before and splitTerm_after:
5564
5565 The terms that split the string that contains the timeStamp of
5566 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5567 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5568 and the splitTerm_after is "x"
5569
5570 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005571 Please look at the "logsearch" Function in onosclidriver.py
Chiyu Chengec63bde2016-11-17 18:11:36 -08005572 '''
5573 if logNum < 0:
5574 main.log.error("Get wrong log number ")
5575 return main.ERROR
5576 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
5577 if len(lines) == 0:
5578 main.log.warn( "Captured timestamp string is empty" )
5579 return main.ERROR
5580 lines = lines[ 0 ]
5581 try:
5582 assert type(lines) is str
5583 # get the target value
5584 line = lines.split( splitTerm_before )
5585 key = line[ 1 ].split( splitTerm_after )
5586 return int( key[ 0 ] )
5587 except IndexError:
5588 main.log.warn( "Index Error!" )
5589 return main.ERROR
5590 except AssertionError:
5591 main.log.warn( "Search Term Not Found " )
5592 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005593
5594 def workQueueAdd( self, queueName, value ):
5595 """
5596 CLI command to add a string to the specified Work Queue.
5597 This function uses the distributed primitives test app, which
5598 gives some cli access to distributed primitives for testing
5599 purposes only.
5600
5601 Required arguments:
5602 queueName - The name of the queue to add to
5603 value - The value to add to the queue
5604 returns:
5605 main.TRUE on success, main.FALSE on failure and
5606 main.ERROR on error.
5607 """
5608 try:
5609 queueName = str( queueName )
5610 value = str( value )
5611 prefix = "work-queue-test"
5612 operation = "add"
5613 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5614 output = self.distPrimitivesSend( cmdStr )
5615 if "Invalid operation name" in output:
5616 main.log.warn( output )
5617 return main.ERROR
5618 elif "Done" in output:
5619 return main.TRUE
5620 except TypeError:
5621 main.log.exception( self.name + ": Object not as expected" )
5622 return main.ERROR
5623 except Exception:
5624 main.log.exception( self.name + ": Uncaught exception!" )
5625 main.cleanup()
5626 main.exit()
5627
5628 def workQueueAddMultiple( self, queueName, value1, value2 ):
5629 """
5630 CLI command to add two strings to the specified Work Queue.
5631 This function uses the distributed primitives test app, which
5632 gives some cli access to distributed primitives for testing
5633 purposes only.
5634
5635 Required arguments:
5636 queueName - The name of the queue to add to
5637 value1 - The first value to add to the queue
5638 value2 - The second value to add to the queue
5639 returns:
5640 main.TRUE on success, main.FALSE on failure and
5641 main.ERROR on error.
5642 """
5643 try:
5644 queueName = str( queueName )
5645 value1 = str( value1 )
5646 value2 = str( value2 )
5647 prefix = "work-queue-test"
5648 operation = "addMultiple"
5649 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5650 output = self.distPrimitivesSend( cmdStr )
5651 if "Invalid operation name" in output:
5652 main.log.warn( output )
5653 return main.ERROR
5654 elif "Done" in output:
5655 return main.TRUE
5656 except TypeError:
5657 main.log.exception( self.name + ": Object not as expected" )
5658 return main.ERROR
5659 except Exception:
5660 main.log.exception( self.name + ": Uncaught exception!" )
5661 main.cleanup()
5662 main.exit()
5663
5664 def workQueueTakeAndComplete( self, queueName, number=1 ):
5665 """
5666 CLI command to take a value from the specified Work Queue and compelte it.
5667 This function uses the distributed primitives test app, which
5668 gives some cli access to distributed primitives for testing
5669 purposes only.
5670
5671 Required arguments:
5672 queueName - The name of the queue to add to
5673 number - The number of items to take and complete
5674 returns:
5675 main.TRUE on success, main.FALSE on failure and
5676 main.ERROR on error.
5677 """
5678 try:
5679 queueName = str( queueName )
5680 number = str( int( number ) )
5681 prefix = "work-queue-test"
5682 operation = "takeAndComplete"
5683 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5684 output = self.distPrimitivesSend( cmdStr )
5685 if "Invalid operation name" in output:
5686 main.log.warn( output )
5687 return main.ERROR
5688 elif "Done" in output:
5689 return main.TRUE
5690 except TypeError:
5691 main.log.exception( self.name + ": Object not as expected" )
5692 return main.ERROR
5693 except Exception:
5694 main.log.exception( self.name + ": Uncaught exception!" )
5695 main.cleanup()
5696 main.exit()
5697
5698 def workQueueDestroy( self, queueName ):
5699 """
5700 CLI command to destroy the specified Work Queue.
5701 This function uses the distributed primitives test app, which
5702 gives some cli access to distributed primitives for testing
5703 purposes only.
5704
5705 Required arguments:
5706 queueName - The name of the queue to add to
5707 returns:
5708 main.TRUE on success, main.FALSE on failure and
5709 main.ERROR on error.
5710 """
5711 try:
5712 queueName = str( queueName )
5713 prefix = "work-queue-test"
5714 operation = "destroy"
5715 cmdStr = " ".join( [ prefix, queueName, operation ] )
5716 output = self.distPrimitivesSend( cmdStr )
5717 if "Invalid operation name" in output:
5718 main.log.warn( output )
5719 return main.ERROR
5720 return main.TRUE
5721 except TypeError:
5722 main.log.exception( self.name + ": Object not as expected" )
5723 return main.ERROR
5724 except Exception:
5725 main.log.exception( self.name + ": Uncaught exception!" )
5726 main.cleanup()
5727 main.exit()
5728
5729 def workQueueTotalPending( self, queueName ):
5730 """
5731 CLI command to get the Total Pending items of the specified Work Queue.
5732 This function uses the distributed primitives test app, which
5733 gives some cli access to distributed primitives for testing
5734 purposes only.
5735
5736 Required arguments:
5737 queueName - The name of the queue to add to
5738 returns:
5739 The number of Pending items in the specified work queue or
5740 None on error
5741 """
5742 try:
5743 queueName = str( queueName )
5744 prefix = "work-queue-test"
5745 operation = "totalPending"
5746 cmdStr = " ".join( [ prefix, queueName, operation ] )
5747 output = self.distPrimitivesSend( cmdStr )
5748 pattern = r'\d+'
5749 if "Invalid operation name" in output:
5750 main.log.warn( output )
5751 return None
5752 else:
5753 match = re.search( pattern, output )
5754 return match.group(0)
5755 except ( AttributeError, TypeError ):
5756 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5757 return None
5758 except Exception:
5759 main.log.exception( self.name + ": Uncaught exception!" )
5760 main.cleanup()
5761 main.exit()
5762
5763 def workQueueTotalCompleted( self, queueName ):
5764 """
5765 CLI command to get the Total Completed items of the specified Work Queue.
5766 This function uses the distributed primitives test app, which
5767 gives some cli access to distributed primitives for testing
5768 purposes only.
5769
5770 Required arguments:
5771 queueName - The name of the queue to add to
5772 returns:
5773 The number of complete items in the specified work queue or
5774 None on error
5775 """
5776 try:
5777 queueName = str( queueName )
5778 prefix = "work-queue-test"
5779 operation = "totalCompleted"
5780 cmdStr = " ".join( [ prefix, queueName, operation ] )
5781 output = self.distPrimitivesSend( cmdStr )
5782 pattern = r'\d+'
5783 if "Invalid operation name" in output:
5784 main.log.warn( output )
5785 return None
5786 else:
5787 match = re.search( pattern, output )
5788 return match.group(0)
5789 except ( AttributeError, TypeError ):
5790 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5791 return None
5792 except Exception:
5793 main.log.exception( self.name + ": Uncaught exception!" )
5794 main.cleanup()
5795 main.exit()
5796
5797 def workQueueTotalInProgress( self, queueName ):
5798 """
5799 CLI command to get the Total In Progress items of the specified Work Queue.
5800 This function uses the distributed primitives test app, which
5801 gives some cli access to distributed primitives for testing
5802 purposes only.
5803
5804 Required arguments:
5805 queueName - The name of the queue to add to
5806 returns:
5807 The number of In Progress items in the specified work queue or
5808 None on error
5809 """
5810 try:
5811 queueName = str( queueName )
5812 prefix = "work-queue-test"
5813 operation = "totalInProgress"
5814 cmdStr = " ".join( [ prefix, queueName, operation ] )
5815 output = self.distPrimitivesSend( cmdStr )
5816 pattern = r'\d+'
5817 if "Invalid operation name" in output:
5818 main.log.warn( output )
5819 return None
5820 else:
5821 match = re.search( pattern, output )
5822 return match.group(0)
5823 except ( AttributeError, TypeError ):
5824 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5825 return None
5826 except Exception:
5827 main.log.exception( self.name + ": Uncaught exception!" )
5828 main.cleanup()
5829 main.exit()