blob: f6b5d629d00e0b3d47762f00a384c577af3e30a4 [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07004OCT 13 2014
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005Copyright 2014 Open Networking Foundation (ONF)
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07006
7Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
8the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
9or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
10
11 TestON is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 2 of the License, or
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000014 (at your option) any later version.
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070015
16 TestON is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with TestON. If not, see <http://www.gnu.org/licenses/>.
23"""
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000024
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070025"""
andrewonlab95ce8322014-10-13 14:12:04 -040026This driver enters the onos> prompt to issue commands.
27
kelvin8ec71442015-01-15 16:57:00 -080028Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -040029functions and document properly.
30
31If you are a contributor to the driver, please
32list your email here for future contact:
33
34jhall@onlab.us
35andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040036shreya@onlab.us
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +000037jeremyr@opennetworking.org
kelvin8ec71442015-01-15 16:57:00 -080038"""
andrewonlab95ce8322014-10-13 14:12:04 -040039import pexpect
40import re
Jon Hall30b82fa2015-03-04 17:15:43 -080041import json
42import types
Jon Hallbd16b922015-03-26 17:53:15 -070043import time
kelvin-onlaba4074292015-07-09 15:19:49 -070044import os
andrewonlab95ce8322014-10-13 14:12:04 -040045from drivers.common.clidriver import CLI
You Wangdb8cd0a2016-05-26 15:19:45 -070046from core.graph import Graph
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -070047from cStringIO import StringIO
48from itertools import izip
andrewonlab95ce8322014-10-13 14:12:04 -040049
kelvin8ec71442015-01-15 16:57:00 -080050class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040051
kelvin8ec71442015-01-15 16:57:00 -080052 def __init__( self ):
53 """
54 Initialize client
55 """
Jon Hallefbd9792015-03-05 16:11:36 -080056 self.name = None
57 self.home = None
58 self.handle = None
Devin Limdc78e202017-06-09 18:30:07 -070059 self.karafUser = None
60 self.karafPass = None
You Wangdb8cd0a2016-05-26 15:19:45 -070061 self.graph = Graph()
Devin Limdc78e202017-06-09 18:30:07 -070062 super( OnosCliDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080063
Jeremy Ronquillo82705492017-10-18 14:19:55 -070064 def checkOptions( self, var, defaultVar ):
Devin Limdc78e202017-06-09 18:30:07 -070065 if var is None or var == "":
66 return defaultVar
67 return var
Jeremy Ronquillo82705492017-10-18 14:19:55 -070068
kelvin8ec71442015-01-15 16:57:00 -080069 def connect( self, **connectargs ):
70 """
andrewonlab95ce8322014-10-13 14:12:04 -040071 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080072 """
andrewonlab95ce8322014-10-13 14:12:04 -040073 try:
74 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080075 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070076 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040077 for key in self.options:
78 if key == "home":
Devin Limdc78e202017-06-09 18:30:07 -070079 self.home = self.options[ key ]
80 elif key == "karaf_username":
81 self.karafUser = self.options[ key ]
82 elif key == "karaf_password":
83 self.karafPass = self.options[ key ]
84
Jeremy Ronquillo82705492017-10-18 14:19:55 -070085 self.home = self.checkOptions( self.home, "~/onos" )
86 self.karafUser = self.checkOptions( self.karafUser, self.user_name )
87 self.karafPass = self.checkOptions( self.karafPass, self.pwd )
andrewonlab95ce8322014-10-13 14:12:04 -040088
kelvin-onlaba4074292015-07-09 15:19:49 -070089 for key in self.options:
90 if key == 'onosIp':
91 self.onosIp = self.options[ 'onosIp' ]
92 break
93
kelvin8ec71442015-01-15 16:57:00 -080094 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070095
96 try:
Jon Hallc6793552016-01-19 14:18:37 -080097 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070098 self.ip_address = os.getenv( str( self.ip_address ) )
99 else:
100 main.log.info( self.name +
101 ": Trying to connect to " +
102 self.ip_address )
103
104 except KeyError:
105 main.log.info( "Invalid host name," +
106 " connecting to local host instead" )
107 self.ip_address = 'localhost'
108 except Exception as inst:
109 main.log.error( "Uncaught exception: " + str( inst ) )
110
kelvin8ec71442015-01-15 16:57:00 -0800111 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800112 user_name=self.user_name,
113 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800114 port=self.port,
115 pwd=self.pwd,
116 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400117
kelvin8ec71442015-01-15 16:57:00 -0800118 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700119 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400120 if self.handle:
121 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800122 else:
123 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400124 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800125 except TypeError:
126 main.log.exception( self.name + ": Object not as expected" )
127 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400128 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800129 main.log.error( self.name + ": EOF exception found" )
130 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700131 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800132 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800133 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700134 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400135
kelvin8ec71442015-01-15 16:57:00 -0800136 def disconnect( self ):
137 """
andrewonlab95ce8322014-10-13 14:12:04 -0400138 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800139 """
Jon Halld61331b2015-02-17 16:35:47 -0800140 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400141 try:
Jon Hall61282e32015-03-19 11:34:11 -0700142 if self.handle:
143 i = self.logout()
144 if i == main.TRUE:
145 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700146 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700147 self.handle.sendline( "exit" )
148 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800149 except TypeError:
150 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800151 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400152 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800153 main.log.error( self.name + ": EOF exception found" )
154 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700155 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700156 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700157 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800158 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800159 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400160 response = main.FALSE
161 return response
162
kelvin8ec71442015-01-15 16:57:00 -0800163 def logout( self ):
164 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500165 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700166 Returns main.TRUE if exited CLI and
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000167 main.FALSE on timeout (not guranteed you are disconnected)
Jon Hall61282e32015-03-19 11:34:11 -0700168 None on TypeError
169 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800170 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500171 try:
Jon Hall61282e32015-03-19 11:34:11 -0700172 if self.handle:
173 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700174 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ],
Jon Hall61282e32015-03-19 11:34:11 -0700175 timeout=10 )
176 if i == 0: # In ONOS CLI
177 self.handle.sendline( "logout" )
Devin Limdc78e202017-06-09 18:30:07 -0700178 j = self.handle.expect( [ self.prompt,
Jon Hallbfe00002016-04-05 10:23:54 -0700179 "Command not found:",
180 pexpect.TIMEOUT ] )
181 if j == 0: # Successfully logged out
182 return main.TRUE
183 elif j == 1 or j == 2:
184 # ONOS didn't fully load, and logout command isn't working
185 # or the command timed out
186 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700187 try:
Devin Limdc78e202017-06-09 18:30:07 -0700188 self.handle.expect( self.prompt )
Jon Hall64ab3bd2016-05-13 11:29:44 -0700189 except pexpect.TIMEOUT:
190 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700191 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700192 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700193 main.log.warn( "Unknown repsonse to logout command: '{}'",
194 repr( self.handle.before ) )
195 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700196 elif i == 1: # not in CLI
197 return main.TRUE
198 elif i == 3: # Timeout
199 return main.FALSE
200 else:
andrewonlab9627f432014-11-14 12:45:10 -0500201 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800202 except TypeError:
203 main.log.exception( self.name + ": Object not as expected" )
204 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500205 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800206 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700207 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700208 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700209 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700210 main.log.error( self.name +
211 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800212 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800213 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700214 main.cleanAndExit()
andrewonlab38d2b4a2014-11-13 16:28:47 -0500215
kelvin-onlabd3b64892015-01-20 13:26:24 -0800216 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800217 """
andrewonlab95ce8322014-10-13 14:12:04 -0400218 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800219
andrewonlab95ce8322014-10-13 14:12:04 -0400220 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800221 """
andrewonlab95ce8322014-10-13 14:12:04 -0400222 try:
223 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800224 main.log.error( "Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700225 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400226 else:
kelvin8ec71442015-01-15 16:57:00 -0800227 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800229 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400230 # and that this driver will have to change accordingly
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700231 self.handle.expect( str( cellname ) )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800232 handleBefore = self.handle.before
233 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800234 # Get the rest of the handle
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700235 self.handle.sendline( "" )
236 self.handle.expect( self.prompt )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800237 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400238
kelvin-onlabd3b64892015-01-20 13:26:24 -0800239 main.log.info( "Cell call returned: " + handleBefore +
240 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400241
242 return main.TRUE
243
Jon Halld4d4b372015-01-28 16:02:41 -0800244 except TypeError:
245 main.log.exception( self.name + ": Object not as expected" )
246 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400247 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800248 main.log.error( self.name + ": eof exception found" )
249 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700250 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800251 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800252 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700253 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -0800254
pingping-lin57a56ce2015-05-20 16:43:48 -0700255 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800256 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800257 """
Jon Hallefbd9792015-03-05 16:11:36 -0800258 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800259 by user would be used to set the current karaf shell idle timeout.
260 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800261 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800262 Below is an example to start a session with 60 seconds idle timeout
263 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800264
Hari Krishna25d42f72015-01-05 15:08:28 -0800265 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800266 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800267
kelvin-onlabd3b64892015-01-20 13:26:24 -0800268 Note: karafTimeout is left as str so that this could be read
269 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800270 """
You Wangf69ab392016-01-26 16:34:38 -0800271 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400272 try:
Jon Hall67253832016-12-05 09:47:13 -0800273 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800274 self.handle.sendline( "" )
275 x = self.handle.expect( [
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700276 self.prompt, "onos>" ], commandlineTimeout )
andrewonlab48829f62014-11-17 13:49:01 -0500277 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800278 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500279 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400280
Jon Hall67253832016-12-05 09:47:13 -0800281 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800282 if waitForStart:
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800283 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
284 startCliCommand = "onos-wait-for-start "
Chiyu Chengef109502016-11-21 15:51:38 -0800285 else:
286 startCliCommand = "onos "
287 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800288 i = self.handle.expect( [
289 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700290 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400291
292 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800293 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800294 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800295 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800296 "config:property-set -p org.apache.karaf.shell\
297 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800298 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700299 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800300 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800301 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400302 return main.TRUE
303 else:
kelvin8ec71442015-01-15 16:57:00 -0800304 # If failed, send ctrl+c to process and try again
305 main.log.info( "Starting CLI failed. Retrying..." )
306 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800307 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800308 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
309 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400310 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800311 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800312 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800313 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800314 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800315 "config:property-set -p org.apache.karaf.shell\
316 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800317 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700318 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800319 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800320 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400321 return main.TRUE
322 else:
kelvin8ec71442015-01-15 16:57:00 -0800323 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800324 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400325 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400326
Jon Halld4d4b372015-01-28 16:02:41 -0800327 except TypeError:
328 main.log.exception( self.name + ": Object not as expected" )
329 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400330 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800331 main.log.error( self.name + ": EOF exception found" )
332 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700333 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800334 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800335 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700336 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400337
suibin zhang116647a2016-05-06 16:30:09 -0700338 def startCellCli( self, karafTimeout="",
339 commandlineTimeout=10, onosStartTimeout=60 ):
340 """
341 Start CLI on onos ecll handle.
342
343 karafTimeout is an optional argument. karafTimeout value passed
344 by user would be used to set the current karaf shell idle timeout.
345 Note that when ever this property is modified the shell will exit and
346 the subsequent login would reflect new idle timeout.
347 Below is an example to start a session with 60 seconds idle timeout
348 ( input value is in milliseconds ):
349
350 tValue = "60000"
351
352 Note: karafTimeout is left as str so that this could be read
353 and passed to startOnosCli from PARAMS file as str.
354 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000355
suibin zhang116647a2016-05-06 16:30:09 -0700356 try:
357 self.handle.sendline( "" )
358 x = self.handle.expect( [
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700359 self.prompt, "onos>" ], commandlineTimeout )
suibin zhang116647a2016-05-06 16:30:09 -0700360
361 if x == 1:
362 main.log.info( "ONOS cli is already running" )
363 return main.TRUE
364
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800365 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
suibin zhang116647a2016-05-06 16:30:09 -0700366 self.handle.sendline( "/opt/onos/bin/onos" )
367 i = self.handle.expect( [
368 "onos>",
369 pexpect.TIMEOUT ], onosStartTimeout )
370
371 if i == 0:
372 main.log.info( self.name + " CLI Started successfully" )
373 if karafTimeout:
374 self.handle.sendline(
375 "config:property-set -p org.apache.karaf.shell\
376 sshIdleTimeout " +
377 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700378 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700379 self.handle.sendline( "/opt/onos/bin/onos" )
380 self.handle.expect( "onos>" )
381 return main.TRUE
382 else:
383 # If failed, send ctrl+c to process and try again
384 main.log.info( "Starting CLI failed. Retrying..." )
385 self.handle.send( "\x03" )
386 self.handle.sendline( "/opt/onos/bin/onos" )
387 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
388 timeout=30 )
389 if i == 0:
390 main.log.info( self.name + " CLI Started " +
391 "successfully after retry attempt" )
392 if karafTimeout:
393 self.handle.sendline(
394 "config:property-set -p org.apache.karaf.shell\
395 sshIdleTimeout " +
396 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700397 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700398 self.handle.sendline( "/opt/onos/bin/onos" )
399 self.handle.expect( "onos>" )
400 return main.TRUE
401 else:
402 main.log.error( "Connection to CLI " +
403 self.name + " timeout" )
404 return main.FALSE
405
406 except TypeError:
407 main.log.exception( self.name + ": Object not as expected" )
408 return None
409 except pexpect.EOF:
410 main.log.error( self.name + ": EOF exception found" )
411 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700412 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700413 except Exception:
414 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700415 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700416
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800417 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800418 """
419 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800420 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800421 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700422 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800423 Available level: DEBUG, TRACE, INFO, WARN, ERROR
424 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800425 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800426 """
427 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800428 lvlStr = ""
429 if level:
430 lvlStr = "--level=" + level
431
kelvin-onlab338f5512015-02-06 10:53:16 -0800432 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700433 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800434 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800435
kelvin-onlab9f541032015-02-04 16:19:53 -0800436 response = self.handle.before
437 if re.search( "Error", response ):
438 return main.FALSE
439 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700440 except pexpect.TIMEOUT:
441 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700442 if noExit:
443 main.cleanup()
444 return None
445 else:
Devin Lim44075962017-08-11 10:56:37 -0700446 main.cleanAndExit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800447 except pexpect.EOF:
448 main.log.error( self.name + ": EOF exception found" )
449 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700450 if noExit:
451 main.cleanup()
452 return None
453 else:
Devin Lim44075962017-08-11 10:56:37 -0700454 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800455 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800456 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700457 if noExit:
458 main.cleanup()
459 return None
460 else:
Devin Lim44075962017-08-11 10:56:37 -0700461 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400462
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700463 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, dollarSign=False ):
kelvin8ec71442015-01-15 16:57:00 -0800464 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800465 Send a completely user specified string to
466 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400467 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800468
YPZhang14a4aa92016-07-15 13:37:15 -0700469 if noExit is True, TestON will not exit, and return None
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700470 if dollarSign is True, TestON will not expect for '$' as a new CLI or onos> prompt
471 since '$' can be in the output.
YPZhangebf9eb52016-05-12 15:20:24 -0700472
andrewonlaba18f6bf2014-10-13 19:31:54 -0400473 Warning: There are no sanity checking to commands
474 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800475
kelvin8ec71442015-01-15 16:57:00 -0800476 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400477 try:
Jon Halla495f562016-05-16 18:03:26 -0700478 # Try to reconnect if disconnected from cli
479 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700480 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ] )
Jon Halla495f562016-05-16 18:03:26 -0700481 if i == 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700482 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700483 if self.onosIp:
484 main.log.warn( "Trying to reconnect " + self.onosIp )
485 reconnectResult = self.startOnosCli( self.onosIp )
486 if reconnectResult:
487 main.log.info( self.name + ": onos cli session reconnected." )
488 else:
489 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700490 if noExit:
491 return None
492 else:
Devin Lim44075962017-08-11 10:56:37 -0700493 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700494 else:
Devin Lim44075962017-08-11 10:56:37 -0700495 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700496 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700497 main.log.warn( "Timeout when testing cli responsiveness" )
498 main.log.debug( self.handle.before )
499 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700500 self.handle.expect( "onos>" )
501
Jon Hall14a03b52016-05-11 12:07:30 -0700502 if debug:
503 # NOTE: This adds and average of .4 seconds per call
504 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700505 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 self.handle.sendline( cmdStr )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700507 if dollarSign:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700508 i = self.handle.expect( [ "onos>" ], timeout )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700509 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700510 i = self.handle.expect( [ "onos>", self.prompt ], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800511 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800512 # TODO: do something with i
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000513 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800514 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700515 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700516 main.log.debug( self.name + ": Raw output" )
517 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700518
519 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800520 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800521 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700522 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700523 main.log.debug( self.name + ": ansiEscape output" )
524 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700525
kelvin-onlabfb521662015-02-27 09:52:40 -0800526 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000527 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700528 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700529 main.log.debug( self.name + ": Removed extra returns " +
530 "from output" )
531 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700532
533 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800534 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700535 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700536 main.log.debug( self.name + ": parsed and stripped output" )
537 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700538
Jon Hall63604932015-02-26 17:09:50 -0800539 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700540 output = response.split( cmdStr.strip(), 1 )
541 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700542 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700543 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700544 main.log.debug( self.name + ": " + repr( r ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700545 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800546 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800547 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800548 return output
GlennRCed771242016-01-13 17:02:47 -0800549 except pexpect.TIMEOUT:
550 main.log.error( self.name + ":ONOS timeout" )
551 if debug:
552 main.log.debug( self.handle.before )
553 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700554 except IndexError:
555 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700556 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700557 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800558 except TypeError:
559 main.log.exception( self.name + ": Object not as expected" )
560 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400561 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800562 main.log.error( self.name + ": EOF exception found" )
563 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700564 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700565 return None
566 else:
Devin Lim44075962017-08-11 10:56:37 -0700567 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800568 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800569 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700570 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700571 return None
572 else:
Devin Lim44075962017-08-11 10:56:37 -0700573 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400574
kelvin8ec71442015-01-15 16:57:00 -0800575 # IMPORTANT NOTE:
576 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800577 # the cli command changing 'a:b' with 'aB'.
578 # Ex ) onos:topology > onosTopology
579 # onos:links > onosLinks
580 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800581
kelvin-onlabd3b64892015-01-20 13:26:24 -0800582 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800583 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400584 Adds a new cluster node by ID and address information.
585 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800586 * nodeId
587 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400588 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800589 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800590 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400591 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800592 cmdStr = "add-node " + str( nodeId ) + " " +\
593 str( ONOSIp ) + " " + str( tcpPort )
594 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700595 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800596 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800597 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800598 main.log.error( "Error in adding node" )
599 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800600 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400601 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400603 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800604 except AssertionError:
605 main.log.exception( "" )
606 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800607 except TypeError:
608 main.log.exception( self.name + ": Object not as expected" )
609 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400610 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800611 main.log.error( self.name + ": EOF exception found" )
612 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700613 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800614 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800615 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700616 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400617
kelvin-onlabd3b64892015-01-20 13:26:24 -0800618 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800619 """
andrewonlab86dc3082014-10-13 18:18:38 -0400620 Removes a cluster by ID
621 Issues command: 'remove-node [<node-id>]'
622 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800623 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800624 """
andrewonlab86dc3082014-10-13 18:18:38 -0400625 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400626
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700628 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700629 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800630 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700631 if re.search( "Error", handle ):
632 main.log.error( "Error in removing node" )
633 main.log.error( handle )
634 return main.FALSE
635 else:
636 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800637 except AssertionError:
638 main.log.exception( "" )
639 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800640 except TypeError:
641 main.log.exception( self.name + ": Object not as expected" )
642 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400643 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800644 main.log.error( self.name + ": EOF exception found" )
645 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700646 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800647 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800648 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700649 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400650
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700651 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800652 """
andrewonlab7c211572014-10-15 16:45:20 -0400653 List the nodes currently visible
654 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700655 Optional argument:
656 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800657 """
andrewonlab7c211572014-10-15 16:45:20 -0400658 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700659 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700660 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700661 cmdStr += " -j"
662 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700663 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800664 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700665 return output
Jon Hallc6793552016-01-19 14:18:37 -0800666 except AssertionError:
667 main.log.exception( "" )
668 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800669 except TypeError:
670 main.log.exception( self.name + ": Object not as expected" )
671 return None
andrewonlab7c211572014-10-15 16:45:20 -0400672 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800673 main.log.error( self.name + ": EOF exception found" )
674 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700675 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800676 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800677 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700678 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400679
kelvin8ec71442015-01-15 16:57:00 -0800680 def topology( self ):
681 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700682 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700683 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700684 Return:
685 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800686 """
andrewonlab95ce8322014-10-13 14:12:04 -0400687 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700688 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800690 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800691 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700692 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400693 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800694 except AssertionError:
695 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800696 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800697 except TypeError:
698 main.log.exception( self.name + ": Object not as expected" )
699 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400700 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800701 main.log.error( self.name + ": EOF exception found" )
702 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700703 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800704 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800705 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700706 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800707
jenkins7ead5a82015-03-13 10:28:21 -0700708 def deviceRemove( self, deviceId ):
709 """
710 Removes particular device from storage
711
712 TODO: refactor this function
713 """
714 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700715 cmdStr = "device-remove " + str( deviceId )
716 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800717 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800718 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700719 if re.search( "Error", handle ):
720 main.log.error( "Error in removing device" )
721 main.log.error( handle )
722 return main.FALSE
723 else:
724 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800725 except AssertionError:
726 main.log.exception( "" )
727 return None
jenkins7ead5a82015-03-13 10:28:21 -0700728 except TypeError:
729 main.log.exception( self.name + ": Object not as expected" )
730 return None
731 except pexpect.EOF:
732 main.log.error( self.name + ": EOF exception found" )
733 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700734 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700735 except Exception:
736 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700737 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700738
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800740 """
Jon Hall7b02d952014-10-17 20:14:54 -0400741 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400742 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800743 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800744 """
andrewonlab86dc3082014-10-13 18:18:38 -0400745 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700746 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700748 cmdStr += " -j"
749 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800750 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800751 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700752 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800753 except AssertionError:
754 main.log.exception( "" )
755 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800756 except TypeError:
757 main.log.exception( self.name + ": Object not as expected" )
758 return None
andrewonlab7c211572014-10-15 16:45:20 -0400759 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800760 main.log.error( self.name + ": EOF exception found" )
761 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700762 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800763 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800764 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700765 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400766
kelvin-onlabd3b64892015-01-20 13:26:24 -0800767 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800768 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800769 This balances the devices across all controllers
770 by issuing command: 'onos> onos:balance-masters'
771 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800772 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800773 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800774 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700775 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800776 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800777 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700778 if re.search( "Error", handle ):
779 main.log.error( "Error in balancing masters" )
780 main.log.error( handle )
781 return main.FALSE
782 else:
783 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800784 except AssertionError:
785 main.log.exception( "" )
786 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800787 except TypeError:
788 main.log.exception( self.name + ": Object not as expected" )
789 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800790 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800791 main.log.error( self.name + ": EOF exception found" )
792 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700793 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800794 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800795 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700796 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800797
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000798 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700799 """
800 Returns the output of the masters command.
801 Optional argument:
802 * jsonFormat - boolean indicating if you want output in json
803 """
804 try:
805 cmdStr = "onos:masters"
806 if jsonFormat:
807 cmdStr += " -j"
808 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700809 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800810 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700811 return output
Jon Hallc6793552016-01-19 14:18:37 -0800812 except AssertionError:
813 main.log.exception( "" )
814 return None
acsmars24950022015-07-30 18:00:43 -0700815 except TypeError:
816 main.log.exception( self.name + ": Object not as expected" )
817 return None
818 except pexpect.EOF:
819 main.log.error( self.name + ": EOF exception found" )
820 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700821 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700822 except Exception:
823 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700824 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700825
Jon Hallc6793552016-01-19 14:18:37 -0800826 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700827 """
828 Uses the master command to check that the devices' leadership
829 is evenly divided
830
831 Dependencies: checkMasters() and summary()
832
Jon Hall6509dbf2016-06-21 17:01:17 -0700833 Returns main.TRUE if the devices are balanced
834 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700835 Exits on Exception
836 Returns None on TypeError
837 """
838 try:
Jon Hallc6793552016-01-19 14:18:37 -0800839 summaryOutput = self.summary()
840 totalDevices = json.loads( summaryOutput )[ "devices" ]
841 except ( TypeError, ValueError ):
842 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
843 return None
844 try:
acsmars24950022015-07-30 18:00:43 -0700845 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800846 mastersOutput = self.checkMasters()
847 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700848 first = masters[ 0 ][ "size" ]
849 for master in masters:
850 totalOwnedDevices += master[ "size" ]
851 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
852 main.log.error( "Mastership not balanced" )
853 main.log.info( "\n" + self.checkMasters( False ) )
854 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700855 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700856 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700857 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800858 except ( TypeError, ValueError ):
859 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700860 return None
861 except pexpect.EOF:
862 main.log.error( self.name + ": EOF exception found" )
863 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700864 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700865 except Exception:
866 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700867 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700868
YPZhangfebf7302016-05-24 16:45:56 -0700869 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800870 """
Jon Halle8217482014-10-17 13:49:14 -0400871 Lists all core links
872 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800873 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800874 """
Jon Halle8217482014-10-17 13:49:14 -0400875 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700876 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800877 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700878 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700879 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800880 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800881 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700882 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800883 except AssertionError:
884 main.log.exception( "" )
885 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800886 except TypeError:
887 main.log.exception( self.name + ": Object not as expected" )
888 return None
Jon Halle8217482014-10-17 13:49:14 -0400889 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800890 main.log.error( self.name + ": EOF exception found" )
891 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700892 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800893 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800894 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700895 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400896
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800898 """
Jon Halle8217482014-10-17 13:49:14 -0400899 Lists all ports
900 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800901 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800902 """
Jon Halle8217482014-10-17 13:49:14 -0400903 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700904 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800905 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700906 cmdStr += " -j"
907 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800908 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800909 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700910 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800911 except AssertionError:
912 main.log.exception( "" )
913 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800914 except TypeError:
915 main.log.exception( self.name + ": Object not as expected" )
916 return None
Jon Halle8217482014-10-17 13:49:14 -0400917 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800918 main.log.error( self.name + ": EOF exception found" )
919 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700920 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800921 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800922 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700923 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400924
kelvin-onlabd3b64892015-01-20 13:26:24 -0800925 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800926 """
Jon Hall983a1702014-10-28 18:44:22 -0400927 Lists all devices and the controllers with roles assigned to them
928 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800929 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800930 """
andrewonlab7c211572014-10-15 16:45:20 -0400931 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700932 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800933 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700934 cmdStr += " -j"
935 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800936 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800937 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700938 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800939 except AssertionError:
940 main.log.exception( "" )
941 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800942 except TypeError:
943 main.log.exception( self.name + ": Object not as expected" )
944 return None
Jon Hall983a1702014-10-28 18:44:22 -0400945 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800946 main.log.error( self.name + ": EOF exception found" )
947 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700948 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800949 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800950 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700951 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -0400952
kelvin-onlabd3b64892015-01-20 13:26:24 -0800953 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800954 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800955 Given the a string containing the json representation of the "roles"
956 cli command and a partial or whole device id, returns a json object
957 containing the roles output for the first device whose id contains
958 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400959
960 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800961 A dict of the role assignments for the given device or
962 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800963 """
Jon Hall983a1702014-10-28 18:44:22 -0400964 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400966 return None
967 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800968 rawRoles = self.roles()
969 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800970 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800972 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800973 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400974 return device
975 return None
Jon Hallc6793552016-01-19 14:18:37 -0800976 except ( TypeError, ValueError ):
977 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800978 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400979 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800980 main.log.error( self.name + ": EOF exception found" )
981 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700982 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800983 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800984 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700985 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -0800986
kelvin-onlabd3b64892015-01-20 13:26:24 -0800987 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800988 """
Jon Hall94fd0472014-12-08 11:52:42 -0800989 Iterates through each device and checks if there is a master assigned
990 Returns: main.TRUE if each device has a master
991 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800992 """
Jon Hall94fd0472014-12-08 11:52:42 -0800993 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 rawRoles = self.roles()
995 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800996 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800997 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800998 # print device
999 if device[ 'master' ] == "none":
1000 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001001 return main.FALSE
1002 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001003 except ( TypeError, ValueError ):
1004 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001005 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001006 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001007 main.log.error( self.name + ": EOF exception found" )
1008 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001009 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001010 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001011 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001012 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001013
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001015 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001016 Returns string of paths, and the cost.
1017 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001018 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001019 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001020 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1021 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001022 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001023 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001024 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001025 main.log.error( "Error in getting paths" )
1026 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001027 else:
kelvin8ec71442015-01-15 16:57:00 -08001028 path = handle.split( ";" )[ 0 ]
1029 cost = handle.split( ";" )[ 1 ]
1030 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001031 except AssertionError:
1032 main.log.exception( "" )
1033 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001034 except TypeError:
1035 main.log.exception( self.name + ": Object not as expected" )
1036 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001037 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001038 main.log.error( self.name + ": EOF exception found" )
1039 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001040 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001041 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001042 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001043 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001044
kelvin-onlabd3b64892015-01-20 13:26:24 -08001045 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001046 """
Jon Hallffb386d2014-11-21 13:43:38 -08001047 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001048 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001049 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001050 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001051 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001052 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001054 cmdStr += " -j"
1055 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001056 if handle:
1057 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001058 # TODO: Maybe make this less hardcoded
1059 # ConsistentMap Exceptions
1060 assert "org.onosproject.store.service" not in handle
1061 # Node not leader
1062 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001063 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001064 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001065 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001066 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001067 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001068 except TypeError:
1069 main.log.exception( self.name + ": Object not as expected" )
1070 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001071 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001072 main.log.error( self.name + ": EOF exception found" )
1073 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001074 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001075 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001076 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001077 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001078
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001080 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001081 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001082
Jon Hallefbd9792015-03-05 16:11:36 -08001083 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001084 partial mac address
1085
Jon Hall42db6dc2014-10-24 19:03:48 -04001086 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001087 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001088 try:
kelvin8ec71442015-01-15 16:57:00 -08001089 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001090 return None
1091 else:
1092 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 rawHosts = self.hosts()
1094 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001095 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001097 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001098 if not host:
1099 pass
1100 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001101 return host
1102 return None
Jon Hallc6793552016-01-19 14:18:37 -08001103 except ( TypeError, ValueError ):
1104 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001105 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001106 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001107 main.log.error( self.name + ": EOF exception found" )
1108 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001109 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001110 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001111 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001112 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001113
kelvin-onlabd3b64892015-01-20 13:26:24 -08001114 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001115 """
1116 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001117 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001118
andrewonlab3f0a4af2014-10-17 12:25:14 -04001119 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001121 IMPORTANT:
1122 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001123 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001124 Furthermore, it assumes that value of VLAN is '-1'
1125 Description:
kelvin8ec71442015-01-15 16:57:00 -08001126 Converts mininet hosts ( h1, h2, h3... ) into
1127 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1128 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001129 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001130 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001131
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001133 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 hostHex = hex( int( host ) ).zfill( 12 )
1135 hostHex = str( hostHex ).replace( 'x', '0' )
1136 i = iter( str( hostHex ) )
1137 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1138 hostHex = hostHex + "/-1"
1139 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001140
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001142
Jon Halld4d4b372015-01-28 16:02:41 -08001143 except TypeError:
1144 main.log.exception( self.name + ": Object not as expected" )
1145 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001146 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001147 main.log.error( self.name + ": EOF exception found" )
1148 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001149 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001150 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001151 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001152 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001153
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001154 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001155 """
andrewonlabe6745342014-10-17 14:29:13 -04001156 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001157 * hostIdOne: ONOS host id for host1
1158 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001159 Optional:
1160 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001161 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001162 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001163 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001164 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001165 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001166 Returns:
1167 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001168 """
andrewonlabe6745342014-10-17 14:29:13 -04001169 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001170 cmdStr = "add-host-intent "
1171 if vlanId:
1172 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001173 if setVlan:
1174 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001175 if encap:
1176 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001177 if bandwidth:
1178 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001179 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001180 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001181 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001182 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001183 if re.search( "Error", handle ):
1184 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001185 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001186 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001187 else:
1188 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001189 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001190 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001191 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001192 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001193 else:
1194 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001195 main.log.debug( "Response from ONOS was: " +
1196 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001197 return None
Jon Hallc6793552016-01-19 14:18:37 -08001198 except AssertionError:
1199 main.log.exception( "" )
1200 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001201 except TypeError:
1202 main.log.exception( self.name + ": Object not as expected" )
1203 return None
andrewonlabe6745342014-10-17 14:29:13 -04001204 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001205 main.log.error( self.name + ": EOF exception found" )
1206 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001207 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001208 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001209 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001210 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001211
kelvin-onlabd3b64892015-01-20 13:26:24 -08001212 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001213 """
andrewonlab7b31d232014-10-24 13:31:47 -04001214 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001215 * ingressDevice: device id of ingress device
1216 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001217 Optional:
1218 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001219 Description:
1220 Adds an optical intent by specifying an ingress and egress device
1221 Returns:
1222 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001223 """
andrewonlab7b31d232014-10-24 13:31:47 -04001224 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001225 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1226 " " + str( egressDevice )
1227 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001228 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001229 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001230 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001231 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001232 main.log.error( "Error in adding Optical intent" )
1233 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001234 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001235 main.log.info( "Optical intent installed between " +
1236 str( ingressDevice ) + " and " +
1237 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001238 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001239 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001240 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001241 else:
1242 main.log.error( "Error, intent ID not found" )
1243 return None
Jon Hallc6793552016-01-19 14:18:37 -08001244 except AssertionError:
1245 main.log.exception( "" )
1246 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001247 except TypeError:
1248 main.log.exception( self.name + ": Object not as expected" )
1249 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001250 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001251 main.log.error( self.name + ": EOF exception found" )
1252 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001253 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001254 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001255 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001256 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001257
kelvin-onlabd3b64892015-01-20 13:26:24 -08001258 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001259 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001260 ingressDevice,
1261 egressDevice,
1262 portIngress="",
1263 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001264 ethType="",
1265 ethSrc="",
1266 ethDst="",
1267 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001268 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001269 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001270 ipProto="",
1271 ipSrc="",
1272 ipDst="",
1273 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001274 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001275 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001276 setVlan="",
1277 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001278 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001279 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001280 * ingressDevice: device id of ingress device
1281 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001282 Optional:
1283 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001284 * ethSrc: specify ethSrc ( i.e. src mac addr )
1285 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001286 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001287 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001288 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001289 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001290 * ipSrc: specify ip source address
1291 * ipDst: specify ip destination address
1292 * tcpSrc: specify tcp source port
1293 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001294 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001295 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001296 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001297 Description:
kelvin8ec71442015-01-15 16:57:00 -08001298 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001299 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001300 Returns:
1301 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001302
Jon Halle3f39ff2015-01-13 11:50:53 -08001303 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001304 options developers provide for point-to-point
1305 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001306 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001307 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001308 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001309
Jeremy Songsterff553672016-05-12 17:06:23 -07001310 if ethType:
1311 cmd += " --ethType " + str( ethType )
1312 if ethSrc:
1313 cmd += " --ethSrc " + str( ethSrc )
1314 if ethDst:
1315 cmd += " --ethDst " + str( ethDst )
1316 if bandwidth:
1317 cmd += " --bandwidth " + str( bandwidth )
1318 if lambdaAlloc:
1319 cmd += " --lambda "
1320 if ipProto:
1321 cmd += " --ipProto " + str( ipProto )
1322 if ipSrc:
1323 cmd += " --ipSrc " + str( ipSrc )
1324 if ipDst:
1325 cmd += " --ipDst " + str( ipDst )
1326 if tcpSrc:
1327 cmd += " --tcpSrc " + str( tcpSrc )
1328 if tcpDst:
1329 cmd += " --tcpDst " + str( tcpDst )
1330 if vlanId:
1331 cmd += " -v " + str( vlanId )
1332 if setVlan:
1333 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001334 if encap:
1335 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001336 if protected:
1337 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001338
kelvin8ec71442015-01-15 16:57:00 -08001339 # Check whether the user appended the port
1340 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001341 if "/" in ingressDevice:
1342 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001343 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001344 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001345 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001346 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001347 # Would it make sense to throw an exception and exit
1348 # the test?
1349 return None
andrewonlab36af3822014-11-18 17:48:18 -05001350
kelvin8ec71442015-01-15 16:57:00 -08001351 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001352 str( ingressDevice ) + "/" +\
1353 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001354
kelvin-onlabd3b64892015-01-20 13:26:24 -08001355 if "/" in egressDevice:
1356 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001357 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001358 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001359 main.log.error( "You must specify the egress port" )
1360 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001361
kelvin8ec71442015-01-15 16:57:00 -08001362 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001363 str( egressDevice ) + "/" +\
1364 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001365
kelvin-onlab898a6c62015-01-16 14:13:53 -08001366 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001367 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001368 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001369 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001370 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001371 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001372 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001373 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001374 # TODO: print out all the options in this message?
1375 main.log.info( "Point-to-point intent installed between " +
1376 str( ingressDevice ) + " and " +
1377 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001378 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001379 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001380 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001381 else:
1382 main.log.error( "Error, intent ID not found" )
1383 return None
Jon Hallc6793552016-01-19 14:18:37 -08001384 except AssertionError:
1385 main.log.exception( "" )
1386 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001387 except TypeError:
1388 main.log.exception( self.name + ": Object not as expected" )
1389 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001390 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001391 main.log.error( self.name + ": EOF exception found" )
1392 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001393 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001394 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001395 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001396 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001397
kelvin-onlabd3b64892015-01-20 13:26:24 -08001398 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001399 self,
shahshreyac2f97072015-03-19 17:04:29 -07001400 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001401 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001402 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001403 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001404 ethType="",
1405 ethSrc="",
1406 ethDst="",
1407 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001408 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001409 ipProto="",
1410 ipSrc="",
1411 ipDst="",
1412 tcpSrc="",
1413 tcpDst="",
1414 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001415 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001416 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001417 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001418 partial=False,
1419 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001420 """
shahshreyad0c80432014-12-04 16:56:05 -08001421 Note:
shahshreya70622b12015-03-19 17:19:00 -07001422 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001423 is same. That is, all ingress devices include port numbers
1424 with a "/" or all ingress devices could specify device
1425 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001426 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001427 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001428 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001429 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001430 Optional:
1431 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001432 * ethSrc: specify ethSrc ( i.e. src mac addr )
1433 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001434 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001435 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001436 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001437 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001438 * ipSrc: specify ip source address
1439 * ipDst: specify ip destination address
1440 * tcpSrc: specify tcp source port
1441 * tcpDst: specify tcp destination port
1442 * setEthSrc: action to Rewrite Source MAC Address
1443 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001444 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001445 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001446 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001447 Description:
kelvin8ec71442015-01-15 16:57:00 -08001448 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001449 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001450 Returns:
1451 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001452
Jon Halle3f39ff2015-01-13 11:50:53 -08001453 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001454 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001455 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001456 """
shahshreyad0c80432014-12-04 16:56:05 -08001457 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001458 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001459
Jeremy Songsterff553672016-05-12 17:06:23 -07001460 if ethType:
1461 cmd += " --ethType " + str( ethType )
1462 if ethSrc:
1463 cmd += " --ethSrc " + str( ethSrc )
1464 if ethDst:
1465 cmd += " --ethDst " + str( ethDst )
1466 if bandwidth:
1467 cmd += " --bandwidth " + str( bandwidth )
1468 if lambdaAlloc:
1469 cmd += " --lambda "
1470 if ipProto:
1471 cmd += " --ipProto " + str( ipProto )
1472 if ipSrc:
1473 cmd += " --ipSrc " + str( ipSrc )
1474 if ipDst:
1475 cmd += " --ipDst " + str( ipDst )
1476 if tcpSrc:
1477 cmd += " --tcpSrc " + str( tcpSrc )
1478 if tcpDst:
1479 cmd += " --tcpDst " + str( tcpDst )
1480 if setEthSrc:
1481 cmd += " --setEthSrc " + str( setEthSrc )
1482 if setEthDst:
1483 cmd += " --setEthDst " + str( setEthDst )
1484 if vlanId:
1485 cmd += " -v " + str( vlanId )
1486 if setVlan:
1487 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001488 if partial:
1489 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001490 if encap:
1491 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001492
kelvin8ec71442015-01-15 16:57:00 -08001493 # Check whether the user appended the port
1494 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001495
1496 if portIngressList is None:
1497 for ingressDevice in ingressDeviceList:
1498 if "/" in ingressDevice:
1499 cmd += " " + str( ingressDevice )
1500 else:
1501 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001502 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001503 # TODO: perhaps more meaningful return
1504 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001505 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001506 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001507 for ingressDevice, portIngress in zip( ingressDeviceList,
1508 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001509 cmd += " " + \
1510 str( ingressDevice ) + "/" +\
1511 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001512 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001513 main.log.error( "Device list and port list does not " +
1514 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001515 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001516 if "/" in egressDevice:
1517 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001518 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001519 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001520 main.log.error( "You must specify " +
1521 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001522 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001523
kelvin8ec71442015-01-15 16:57:00 -08001524 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001525 str( egressDevice ) + "/" +\
1526 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001527 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001528 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001529 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001530 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001531 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001532 main.log.error( "Error in adding multipoint-to-singlepoint " +
1533 "intent" )
1534 return None
shahshreyad0c80432014-12-04 16:56:05 -08001535 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001536 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001537 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001538 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001539 else:
1540 main.log.error( "Error, intent ID not found" )
1541 return None
Jon Hallc6793552016-01-19 14:18:37 -08001542 except AssertionError:
1543 main.log.exception( "" )
1544 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001545 except TypeError:
1546 main.log.exception( self.name + ": Object not as expected" )
1547 return None
1548 except pexpect.EOF:
1549 main.log.error( self.name + ": EOF exception found" )
1550 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001551 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001552 except Exception:
1553 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001554 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001555
1556 def addSinglepointToMultipointIntent(
1557 self,
1558 ingressDevice,
1559 egressDeviceList,
1560 portIngress="",
1561 portEgressList=None,
1562 ethType="",
1563 ethSrc="",
1564 ethDst="",
1565 bandwidth="",
1566 lambdaAlloc=False,
1567 ipProto="",
1568 ipSrc="",
1569 ipDst="",
1570 tcpSrc="",
1571 tcpDst="",
1572 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001573 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001574 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001575 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001576 partial=False,
1577 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001578 """
1579 Note:
1580 This function assumes the format of all egress devices
1581 is same. That is, all egress devices include port numbers
1582 with a "/" or all egress devices could specify device
1583 ids and port numbers seperately.
1584 Required:
1585 * EgressDeviceList: List of device ids of egress device
1586 ( Atleast 2 eress devices required in the list )
1587 * ingressDevice: device id of ingress device
1588 Optional:
1589 * ethType: specify ethType
1590 * ethSrc: specify ethSrc ( i.e. src mac addr )
1591 * ethDst: specify ethDst ( i.e. dst mac addr )
1592 * bandwidth: specify bandwidth capacity of link
1593 * lambdaAlloc: if True, intent will allocate lambda
1594 for the specified intent
1595 * ipProto: specify ip protocol
1596 * ipSrc: specify ip source address
1597 * ipDst: specify ip destination address
1598 * tcpSrc: specify tcp source port
1599 * tcpDst: specify tcp destination port
1600 * setEthSrc: action to Rewrite Source MAC Address
1601 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001602 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001603 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001604 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001605 Description:
1606 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1607 specifying device id's and optional fields
1608 Returns:
1609 A string of the intent id or None on error
1610
1611 NOTE: This function may change depending on the
1612 options developers provide for singlepoint-to-multipoint
1613 intent via cli
1614 """
1615 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001616 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001617
Jeremy Songsterff553672016-05-12 17:06:23 -07001618 if ethType:
1619 cmd += " --ethType " + str( ethType )
1620 if ethSrc:
1621 cmd += " --ethSrc " + str( ethSrc )
1622 if ethDst:
1623 cmd += " --ethDst " + str( ethDst )
1624 if bandwidth:
1625 cmd += " --bandwidth " + str( bandwidth )
1626 if lambdaAlloc:
1627 cmd += " --lambda "
1628 if ipProto:
1629 cmd += " --ipProto " + str( ipProto )
1630 if ipSrc:
1631 cmd += " --ipSrc " + str( ipSrc )
1632 if ipDst:
1633 cmd += " --ipDst " + str( ipDst )
1634 if tcpSrc:
1635 cmd += " --tcpSrc " + str( tcpSrc )
1636 if tcpDst:
1637 cmd += " --tcpDst " + str( tcpDst )
1638 if setEthSrc:
1639 cmd += " --setEthSrc " + str( setEthSrc )
1640 if setEthDst:
1641 cmd += " --setEthDst " + str( setEthDst )
1642 if vlanId:
1643 cmd += " -v " + str( vlanId )
1644 if setVlan:
1645 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001646 if partial:
1647 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001648 if encap:
1649 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001650
1651 # Check whether the user appended the port
1652 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001653
kelvin-onlabb9408212015-04-01 13:34:04 -07001654 if "/" in ingressDevice:
1655 cmd += " " + str( ingressDevice )
1656 else:
1657 if not portIngress:
1658 main.log.error( "You must specify " +
1659 "the Ingress port" )
1660 return main.FALSE
1661
1662 cmd += " " +\
1663 str( ingressDevice ) + "/" +\
1664 str( portIngress )
1665
1666 if portEgressList is None:
1667 for egressDevice in egressDeviceList:
1668 if "/" in egressDevice:
1669 cmd += " " + str( egressDevice )
1670 else:
1671 main.log.error( "You must specify " +
1672 "the egress port" )
1673 # TODO: perhaps more meaningful return
1674 return main.FALSE
1675 else:
1676 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001677 for egressDevice, portEgress in zip( egressDeviceList,
1678 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001679 cmd += " " + \
1680 str( egressDevice ) + "/" +\
1681 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001682 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001683 main.log.error( "Device list and port list does not " +
1684 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001685 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001686 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001687 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001688 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001689 # If error, return error message
1690 if re.search( "Error", handle ):
1691 main.log.error( "Error in adding singlepoint-to-multipoint " +
1692 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001693 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001694 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001695 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001696 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001697 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001698 else:
1699 main.log.error( "Error, intent ID not found" )
1700 return None
Jon Hallc6793552016-01-19 14:18:37 -08001701 except AssertionError:
1702 main.log.exception( "" )
1703 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001704 except TypeError:
1705 main.log.exception( self.name + ": Object not as expected" )
1706 return None
shahshreyad0c80432014-12-04 16:56:05 -08001707 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001708 main.log.error( self.name + ": EOF exception found" )
1709 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001710 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001711 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001712 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001713 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001714
Hari Krishna9e232602015-04-13 17:29:08 -07001715 def addMplsIntent(
1716 self,
1717 ingressDevice,
1718 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001719 ingressPort="",
1720 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001721 ethType="",
1722 ethSrc="",
1723 ethDst="",
1724 bandwidth="",
1725 lambdaAlloc=False,
1726 ipProto="",
1727 ipSrc="",
1728 ipDst="",
1729 tcpSrc="",
1730 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001731 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001732 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001733 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001734 """
1735 Required:
1736 * ingressDevice: device id of ingress device
1737 * egressDevice: device id of egress device
1738 Optional:
1739 * ethType: specify ethType
1740 * ethSrc: specify ethSrc ( i.e. src mac addr )
1741 * ethDst: specify ethDst ( i.e. dst mac addr )
1742 * bandwidth: specify bandwidth capacity of link
1743 * lambdaAlloc: if True, intent will allocate lambda
1744 for the specified intent
1745 * ipProto: specify ip protocol
1746 * ipSrc: specify ip source address
1747 * ipDst: specify ip destination address
1748 * tcpSrc: specify tcp source port
1749 * tcpDst: specify tcp destination port
1750 * ingressLabel: Ingress MPLS label
1751 * egressLabel: Egress MPLS label
1752 Description:
1753 Adds MPLS intent by
1754 specifying device id's and optional fields
1755 Returns:
1756 A string of the intent id or None on error
1757
1758 NOTE: This function may change depending on the
1759 options developers provide for MPLS
1760 intent via cli
1761 """
1762 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001763 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001764
Jeremy Songsterff553672016-05-12 17:06:23 -07001765 if ethType:
1766 cmd += " --ethType " + str( ethType )
1767 if ethSrc:
1768 cmd += " --ethSrc " + str( ethSrc )
1769 if ethDst:
1770 cmd += " --ethDst " + str( ethDst )
1771 if bandwidth:
1772 cmd += " --bandwidth " + str( bandwidth )
1773 if lambdaAlloc:
1774 cmd += " --lambda "
1775 if ipProto:
1776 cmd += " --ipProto " + str( ipProto )
1777 if ipSrc:
1778 cmd += " --ipSrc " + str( ipSrc )
1779 if ipDst:
1780 cmd += " --ipDst " + str( ipDst )
1781 if tcpSrc:
1782 cmd += " --tcpSrc " + str( tcpSrc )
1783 if tcpDst:
1784 cmd += " --tcpDst " + str( tcpDst )
1785 if ingressLabel:
1786 cmd += " --ingressLabel " + str( ingressLabel )
1787 if egressLabel:
1788 cmd += " --egressLabel " + str( egressLabel )
1789 if priority:
1790 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001791
1792 # Check whether the user appended the port
1793 # or provided it as an input
1794 if "/" in ingressDevice:
1795 cmd += " " + str( ingressDevice )
1796 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001797 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001798 main.log.error( "You must specify the ingress port" )
1799 return None
1800
1801 cmd += " " + \
1802 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001803 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001804
1805 if "/" in egressDevice:
1806 cmd += " " + str( egressDevice )
1807 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001808 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001809 main.log.error( "You must specify the egress port" )
1810 return None
1811
1812 cmd += " " +\
1813 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001814 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001815
1816 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001817 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001818 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001819 # If error, return error message
1820 if re.search( "Error", handle ):
1821 main.log.error( "Error in adding mpls intent" )
1822 return None
1823 else:
1824 # TODO: print out all the options in this message?
1825 main.log.info( "MPLS intent installed between " +
1826 str( ingressDevice ) + " and " +
1827 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001828 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07001829 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001830 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07001831 else:
1832 main.log.error( "Error, intent ID not found" )
1833 return None
Jon Hallc6793552016-01-19 14:18:37 -08001834 except AssertionError:
1835 main.log.exception( "" )
1836 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001837 except TypeError:
1838 main.log.exception( self.name + ": Object not as expected" )
1839 return None
1840 except pexpect.EOF:
1841 main.log.error( self.name + ": EOF exception found" )
1842 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001843 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001844 except Exception:
1845 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001846 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001847
Jon Hallefbd9792015-03-05 16:11:36 -08001848 def removeIntent( self, intentId, app='org.onosproject.cli',
1849 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001850 """
shahshreya1c818fc2015-02-26 13:44:08 -08001851 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001852 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001853 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001854 -p or --purge: Purge the intent from the store after removal
1855
Jon Halle3f39ff2015-01-13 11:50:53 -08001856 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001857 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001858 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001859 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001860 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001861 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001862 if purge:
1863 cmdStr += " -p"
1864 if sync:
1865 cmdStr += " -s"
1866
1867 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001868 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001869 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001870 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001871 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001872 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001873 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001874 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001875 # TODO: Should this be main.TRUE
1876 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001877 except AssertionError:
1878 main.log.exception( "" )
1879 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001880 except TypeError:
1881 main.log.exception( self.name + ": Object not as expected" )
1882 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001883 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001884 main.log.error( self.name + ": EOF exception found" )
1885 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001886 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001887 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001888 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001889 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04001890
YPZhangfebf7302016-05-24 16:45:56 -07001891 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001892 """
1893 Description:
1894 Remove all the intents
1895 Optional args:-
1896 -s or --sync: Waits for the removal before returning
1897 -p or --purge: Purge the intent from the store after removal
1898 Returns:
1899 Returns main.TRUE if all intents are removed, otherwise returns
1900 main.FALSE; Returns None for exception
1901 """
1902 try:
1903 cmdStr = "remove-intent"
1904 if purge:
1905 cmdStr += " -p"
1906 if sync:
1907 cmdStr += " -s"
1908
1909 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001910 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001911 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08001912 assert "Command not found:" not in handle, handle
1913 if re.search( "Error", handle ):
1914 main.log.error( "Error in removing intent" )
1915 return main.FALSE
1916 else:
1917 return main.TRUE
1918 except AssertionError:
1919 main.log.exception( "" )
1920 return None
1921 except TypeError:
1922 main.log.exception( self.name + ": Object not as expected" )
1923 return None
1924 except pexpect.EOF:
1925 main.log.error( self.name + ": EOF exception found" )
1926 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001927 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001928 except Exception:
1929 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001930 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001931
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001932 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001933 """
1934 Purges all WITHDRAWN Intents
1935 """
1936 try:
1937 cmdStr = "purge-intents"
1938 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001939 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001940 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001941 if re.search( "Error", handle ):
1942 main.log.error( "Error in purging intents" )
1943 return main.FALSE
1944 else:
1945 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001946 except AssertionError:
1947 main.log.exception( "" )
1948 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001949 except TypeError:
1950 main.log.exception( self.name + ": Object not as expected" )
1951 return None
1952 except pexpect.EOF:
1953 main.log.error( self.name + ": EOF exception found" )
1954 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001955 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07001956 except Exception:
1957 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001958 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07001959
Devin Lime6fe3c42017-10-18 16:28:40 -07001960 def wipeout( self ):
1961 """
1962 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
1963 """
1964 try:
1965 cmdStr = "wipe-out please"
1966 handle = self.sendline( cmdStr, timeout=60 )
1967 assert handle is not None, "Error in sendline"
1968 assert "Command not found:" not in handle, handle
1969 return main.TRUE
1970 except AssertionError:
1971 main.log.exception( "" )
1972 return None
1973 except TypeError:
1974 main.log.exception( self.name + ": Object not as expected" )
1975 return None
1976 except pexpect.EOF:
1977 main.log.error( self.name + ": EOF exception found" )
1978 main.log.error( self.name + ": " + self.handle.before )
1979 main.cleanAndExit()
1980 except Exception:
1981 main.log.exception( self.name + ": Uncaught exception!" )
1982 main.cleanAndExit()
1983
kelvin-onlabd3b64892015-01-20 13:26:24 -08001984 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001985 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001986 NOTE: This method should be used after installing application:
1987 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001988 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001989 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001990 Description:
1991 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001992 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001993 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001994 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001995 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001996 cmdStr += " -j"
1997 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001998 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001999 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002000 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002001 except AssertionError:
2002 main.log.exception( "" )
2003 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002004 except TypeError:
2005 main.log.exception( self.name + ": Object not as expected" )
2006 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002007 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002008 main.log.error( self.name + ": EOF exception found" )
2009 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002010 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002011 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002012 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002013 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002014
pingping-lin54b03372015-08-13 14:43:10 -07002015 def ipv4RouteNumber( self ):
2016 """
2017 NOTE: This method should be used after installing application:
2018 onos-app-sdnip
2019 Description:
2020 Obtain the total IPv4 routes number in the system
2021 """
2022 try:
Pratik Parab57963572017-05-09 11:37:54 -07002023 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002024 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002025 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002026 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002027 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002028 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002029 except AssertionError:
2030 main.log.exception( "" )
2031 return None
2032 except ( TypeError, ValueError ):
2033 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002034 return None
2035 except pexpect.EOF:
2036 main.log.error( self.name + ": EOF exception found" )
2037 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002038 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002039 except Exception:
2040 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002041 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002042
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002043 # =============Function to check Bandwidth allocation========
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002044 def allocations( self, jsonFormat = True, dollarSign = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002045 """
2046 Description:
2047 Obtain Bandwidth Allocation Information from ONOS cli.
2048 """
2049 try:
2050 cmdStr = "allocations"
2051 if jsonFormat:
2052 cmdStr += " -j"
2053 handle = self.sendline( cmdStr, timeout=300, dollarSign=True )
2054 assert handle is not None, "Error in sendline"
2055 assert "Command not found:" not in handle, handle
2056 return handle
2057 except AssertionError:
2058 main.log.exception( "" )
2059 return None
2060 except ( TypeError, ValueError ):
2061 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2062 return None
2063 except pexpect.EOF:
2064 main.log.error( self.name + ": EOF exception found" )
2065 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002066 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002067 except Exception:
2068 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002069 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002070
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002071 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002072 """
andrewonlabe6745342014-10-17 14:29:13 -04002073 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002074 Obtain intents from the ONOS cli.
2075 Optional:
2076 * jsonFormat: Enable output formatting in json, default to True
2077 * summary: Whether only output the intent summary, defaults to False
2078 * type: Only output a certain type of intent. This options is valid
2079 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002080 """
andrewonlabe6745342014-10-17 14:29:13 -04002081 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002082 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002083 if summary:
2084 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002085 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002086 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002087 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002088 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002089 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002090 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002091 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002092 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002093 else:
Jon Hallff566d52016-01-15 14:45:36 -08002094 intentType = ""
2095 # IF we want the summary of a specific intent type
2096 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002097 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002098 if intentType in jsonResult.keys():
2099 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002100 else:
Jon Hallff566d52016-01-15 14:45:36 -08002101 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002102 return handle
2103 else:
2104 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002105 except AssertionError:
2106 main.log.exception( "" )
2107 return None
2108 except ( TypeError, ValueError ):
2109 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002110 return None
2111 except pexpect.EOF:
2112 main.log.error( self.name + ": EOF exception found" )
2113 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002114 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002115 except Exception:
2116 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002117 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002118
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002119 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002120 """
You Wangfdcbfc42016-05-16 12:16:53 -07002121 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002122 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002123 list of intent IDs.
2124 Parameters:
2125 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002126 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002127 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002128 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002129 accepted.
2130 Returns a list of dictionaries if a list of intent IDs is accepted,
2131 and each dictionary maps 'id' to the Intent ID and 'state' to
2132 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002133 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002134
kelvin-onlab54400a92015-02-26 18:05:51 -08002135 try:
2136 state = "State is Undefined"
2137 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002138 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002139 else:
Jon Hallc6793552016-01-19 14:18:37 -08002140 rawJson = intentsJson
2141 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002142 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002143 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002144 if intentsId == intent[ 'id' ]:
2145 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002146 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002147 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002148 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002149 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002150 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002151 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002152 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002153 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002154 for intent in parsedIntentsJson:
2155 if intentsId[ i ] == intent[ 'id' ]:
2156 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002157 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002158 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002159 break
Jon Hallefbd9792015-03-05 16:11:36 -08002160 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002161 main.log.warn( "Could not find all intents in ONOS output" )
2162 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002163 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002164 else:
Jon Hall53158082017-05-18 11:17:00 -07002165 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002166 return None
Jon Hallc6793552016-01-19 14:18:37 -08002167 except ( TypeError, ValueError ):
2168 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002169 return None
2170 except pexpect.EOF:
2171 main.log.error( self.name + ": EOF exception found" )
2172 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002173 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002174 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002175 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002176 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002177
Jon Hallf539eb92017-05-22 17:18:42 -07002178 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002179 """
2180 Description:
2181 Check intents state
2182 Required:
2183 intentsId - List of intents ID to be checked
2184 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002185 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002186 state in the list.
2187 *NOTE: You can pass in a list of expected state,
2188 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002189 Return:
Jon Hall53158082017-05-18 11:17:00 -07002190 Returns main.TRUE only if all intent are the same as expected states,
2191 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002192 """
2193 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002194 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002195 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002196
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002197 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002198 intentsDict = []
2199 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002200 if isinstance( intentsId, types.StringType ) \
2201 and intent.get( 'id' ) == intentsId:
2202 intentsDict.append( intent )
2203 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002204 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002205 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002206
2207 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002208 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002209 "getting intents state" )
2210 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002211
2212 if isinstance( expectedState, types.StringType ):
2213 for intents in intentsDict:
2214 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002215 main.log.debug( self.name + " : Intent ID - " +
2216 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002217 " actual state = " +
2218 intents.get( 'state' )
2219 + " does not equal expected state = "
2220 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002221 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002222 elif isinstance( expectedState, types.ListType ):
2223 for intents in intentsDict:
2224 if not any( state == intents.get( 'state' ) for state in
2225 expectedState ):
2226 main.log.debug( self.name + " : Intent ID - " +
2227 intents.get( 'id' ) +
2228 " actual state = " +
2229 intents.get( 'state' ) +
2230 " does not equal expected states = "
2231 + str( expectedState ) )
2232 returnValue = main.FALSE
2233
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002234 if returnValue == main.TRUE:
2235 main.log.info( self.name + ": All " +
2236 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002237 " intents are in " + str( expectedState ) +
2238 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002239 return returnValue
2240 except TypeError:
2241 main.log.exception( self.name + ": Object not as expected" )
2242 return None
2243 except pexpect.EOF:
2244 main.log.error( self.name + ": EOF exception found" )
2245 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002246 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002247 except Exception:
2248 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002249 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002250
Jon Hallf539eb92017-05-22 17:18:42 -07002251 def compareBandwidthAllocations( self, expectedAllocations ):
2252 """
2253 Description:
2254 Compare the allocated bandwidth with the given allocations
2255 Required:
2256 expectedAllocations - The expected ONOS output of the allocations command
2257 Return:
2258 Returns main.TRUE only if all intent are the same as expected states,
2259 otherwise returns main.FALSE.
2260 """
2261 # FIXME: Convert these string comparisons to object comparisons
2262 try:
2263 returnValue = main.TRUE
2264 bandwidthFailed = False
2265 rawAlloc = self.allocations()
2266 expectedFormat = StringIO( expectedAllocations )
2267 ONOSOutput = StringIO( rawAlloc )
2268 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2269 str( expectedFormat ) ) )
2270
2271 for actual, expected in izip( ONOSOutput, expectedFormat ):
2272 actual = actual.rstrip()
2273 expected = expected.rstrip()
2274 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2275 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002276 marker1 = actual.find( 'allocated' )
2277 m1 = actual[ :marker1 ]
2278 marker2 = expected.find( 'allocated' )
2279 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002280 if m1 != m2:
2281 bandwidthFailed = True
2282 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2283 bandwidthFailed = True
2284 expectedFormat.close()
2285 ONOSOutput.close()
2286
2287 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002288 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002289 returnValue = main.FALSE
2290 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 )
Devin Lim44075962017-08-11 10:56:37 -07002297 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002298 except Exception:
2299 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002300 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002301
You Wang66518af2016-05-16 15:32:59 -07002302 def compareIntent( self, intentDict ):
2303 """
2304 Description:
2305 Compare the intent ids and states provided in the argument with all intents in ONOS
2306 Return:
2307 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2308 Arguments:
2309 intentDict: a dictionary which maps intent ids to intent states
2310 """
2311 try:
2312 intentsRaw = self.intents()
2313 intentsJson = json.loads( intentsRaw )
2314 intentDictONOS = {}
2315 for intent in intentsJson:
2316 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002317 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002318 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002319 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002320 str( len( intentDict ) ) + " expected and " +
2321 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002322 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002323 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002324 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002325 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2326 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002327 else:
2328 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2329 main.log.debug( self.name + ": intent ID - " + intentID +
2330 " expected state is " + intentDict[ intentID ] +
2331 " but actual state is " + intentDictONOS[ intentID ] )
2332 returnValue = main.FALSE
2333 intentDictONOS.pop( intentID )
2334 if len( intentDictONOS ) > 0:
2335 returnValue = main.FALSE
2336 for intentID in intentDictONOS.keys():
2337 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002338 if returnValue == main.TRUE:
2339 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2340 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002341 except KeyError:
2342 main.log.exception( self.name + ": KeyError exception found" )
2343 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002344 except ( TypeError, ValueError ):
2345 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002346 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002347 except pexpect.EOF:
2348 main.log.error( self.name + ": EOF exception found" )
2349 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002350 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002351 except Exception:
2352 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002353 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002354
YPZhang14a4aa92016-07-15 13:37:15 -07002355 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002356 """
2357 Description:
2358 Check the number of installed intents.
2359 Optional:
2360 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002361 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002362 Return:
2363 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2364 , otherwise, returns main.FALSE.
2365 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002366
GlennRCed771242016-01-13 17:02:47 -08002367 try:
2368 cmd = "intents -s -j"
2369
2370 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002371 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002372 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002373 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002374 response = json.loads( response )
2375
2376 # get total and installed number, see if they are match
2377 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002378 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002379 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2380 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002381 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002382 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2383 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002384 return main.FALSE
2385
Jon Hallc6793552016-01-19 14:18:37 -08002386 except ( TypeError, ValueError ):
2387 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002388 return None
2389 except pexpect.EOF:
2390 main.log.error( self.name + ": EOF exception found" )
2391 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002392 if noExit:
2393 return main.FALSE
2394 else:
Devin Lim44075962017-08-11 10:56:37 -07002395 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002396 except pexpect.TIMEOUT:
2397 main.log.error( self.name + ": ONOS timeout" )
2398 return None
GlennRCed771242016-01-13 17:02:47 -08002399 except Exception:
2400 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002401 if noExit:
2402 return main.FALSE
2403 else:
Devin Lim44075962017-08-11 10:56:37 -07002404 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002405
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002406 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002407 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002408 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002409 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002410 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002411 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002412 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002413 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002414 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002415 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002416 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002417 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002418 if noCore:
2419 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002420 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002421 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002422 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002423 assert "Command not found:" not in handle, handle
2424 if re.search( "Error:", handle ):
2425 main.log.error( self.name + ": flows() response: " +
2426 str( handle ) )
2427 return handle
2428 except AssertionError:
2429 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002430 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002431 except TypeError:
2432 main.log.exception( self.name + ": Object not as expected" )
2433 return None
Jon Hallc6793552016-01-19 14:18:37 -08002434 except pexpect.TIMEOUT:
2435 main.log.error( self.name + ": ONOS timeout" )
2436 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002437 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002438 main.log.error( self.name + ": EOF exception found" )
2439 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002440 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002441 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002442 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002443 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002444
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002445 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002446 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002447 count = int( count ) if count else 0
2448 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002449
Jon Halle0f0b342017-04-18 11:43:47 -07002450 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002451 """
2452 Description:
GlennRCed771242016-01-13 17:02:47 -08002453 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002454 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2455 if the count of those states is 0, which means all current flows
2456 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002457 Optional:
GlennRCed771242016-01-13 17:02:47 -08002458 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002459 Return:
2460 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002461 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002462 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002463 """
2464 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002465 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002466 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002467 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002468 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002469 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002470 if rawFlows:
2471 # if we didn't get flows or flows function return None, we should return
2472 # main.Flase
2473 checkedStates.append( json.loads( rawFlows ) )
2474 else:
2475 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002476 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002477 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002478 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002479 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002480 except TypeError:
2481 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002482 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002483
GlennRCed771242016-01-13 17:02:47 -08002484 # We want to count PENDING_ADD if isPENDING is true
2485 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002486 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002487 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002488 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002489 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002490 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002491 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002492 except ( TypeError, ValueError ):
2493 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002494 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002495
YPZhang240842b2016-05-17 12:00:50 -07002496 except AssertionError:
2497 main.log.exception( "" )
2498 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002499 except pexpect.TIMEOUT:
2500 main.log.error( self.name + ": ONOS timeout" )
2501 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002502 except pexpect.EOF:
2503 main.log.error( self.name + ": EOF exception found" )
2504 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002505 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002506 except Exception:
2507 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002508 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002509
GlennRCed771242016-01-13 17:02:47 -08002510 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002511 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002512 """
andrewonlab87852b02014-11-19 18:44:19 -05002513 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002514 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002515 a specific point-to-point intent definition
2516 Required:
GlennRCed771242016-01-13 17:02:47 -08002517 * ingress: specify source dpid
2518 * egress: specify destination dpid
2519 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002520 Optional:
GlennRCed771242016-01-13 17:02:47 -08002521 * offset: the keyOffset is where the next batch of intents
2522 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002523 * noExit: If set to True, TestON will not exit if any error when issus command
2524 * getResponse: If set to True, function will return ONOS response.
2525
GlennRCed771242016-01-13 17:02:47 -08002526 Returns: If failed to push test intents, it will returen None,
2527 if successful, return true.
2528 Timeout expection will return None,
2529 TypeError will return false
2530 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002531 """
andrewonlab87852b02014-11-19 18:44:19 -05002532 try:
GlennRCed771242016-01-13 17:02:47 -08002533 if background:
2534 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002535 else:
GlennRCed771242016-01-13 17:02:47 -08002536 back = ""
2537 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002538 ingress,
2539 egress,
2540 batchSize,
2541 offset,
2542 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002543 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002544 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002545 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002546 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002547 if getResponse:
2548 return response
2549
GlennRCed771242016-01-13 17:02:47 -08002550 # TODO: We should handle if there is failure in installation
2551 return main.TRUE
2552
Jon Hallc6793552016-01-19 14:18:37 -08002553 except AssertionError:
2554 main.log.exception( "" )
2555 return None
GlennRCed771242016-01-13 17:02:47 -08002556 except pexpect.TIMEOUT:
2557 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002558 return None
andrewonlab87852b02014-11-19 18:44:19 -05002559 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002560 main.log.error( self.name + ": EOF exception found" )
2561 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002562 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002563 except TypeError:
2564 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002565 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002566 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002567 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002568 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002569
YPZhangebf9eb52016-05-12 15:20:24 -07002570 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002571 """
2572 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002573 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002574 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002575 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002576 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002577 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002578
YPZhangb5d3f832016-01-23 22:54:26 -08002579 try:
YPZhange3109a72016-02-02 11:25:37 -08002580 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002581 cmd = "flows -c added"
2582 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2583 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002584 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002585 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002586 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002587 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002588 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002589 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002590 return None
2591 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002592
You Wangd3cb2ce2016-05-16 14:01:24 -07002593 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002594 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002595 return None
2596 except pexpect.EOF:
2597 main.log.error( self.name + ": EOF exception found" )
2598 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002599 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002600 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002601 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002602 except pexpect.TIMEOUT:
2603 main.log.error( self.name + ": ONOS timeout" )
2604 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002605 except Exception:
2606 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002607 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002608 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002609 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002610
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002611 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002612 """
2613 Description:
2614 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002615 Optional:
2616 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002617 Return:
2618 The number of intents
2619 """
2620 try:
2621 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002622 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002623 if response is None:
2624 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002625 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002626 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002627 except ( TypeError, ValueError ):
2628 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002629 return None
2630 except pexpect.EOF:
2631 main.log.error( self.name + ": EOF exception found" )
2632 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002633 if noExit:
2634 return -1
2635 else:
Devin Lim44075962017-08-11 10:56:37 -07002636 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002637 except Exception:
2638 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002639 if noExit:
2640 return -1
2641 else:
Devin Lim44075962017-08-11 10:56:37 -07002642 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002643
kelvin-onlabd3b64892015-01-20 13:26:24 -08002644 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002645 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002646 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002647 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002648 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002649 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002650 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002651 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002652 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002653 cmdStr += " -j"
2654 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002655 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002656 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002657 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002658 except AssertionError:
2659 main.log.exception( "" )
2660 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002661 except TypeError:
2662 main.log.exception( self.name + ": Object not as expected" )
2663 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002664 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002665 main.log.error( self.name + ": EOF exception found" )
2666 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002667 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002668 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002669 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002670 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002671
kelvin-onlabd3b64892015-01-20 13:26:24 -08002672 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002673 """
2674 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002675 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002676 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002677 """
andrewonlab867212a2014-10-22 20:13:38 -04002678 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002679 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002680 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002681 cmdStr += " -j"
2682 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002683 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002684 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002685 if handle:
2686 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002687 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002688 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002689 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002690 else:
2691 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002692 except AssertionError:
2693 main.log.exception( "" )
2694 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002695 except TypeError:
2696 main.log.exception( self.name + ": Object not as expected" )
2697 return None
andrewonlab867212a2014-10-22 20:13:38 -04002698 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002699 main.log.error( self.name + ": EOF exception found" )
2700 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002701 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002702 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002703 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002704 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002705
kelvin8ec71442015-01-15 16:57:00 -08002706 # Wrapper functions ****************
2707 # Wrapper functions use existing driver
2708 # functions and extends their use case.
2709 # For example, we may use the output of
2710 # a normal driver function, and parse it
2711 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002712
kelvin-onlabd3b64892015-01-20 13:26:24 -08002713 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002714 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002715 Description:
2716 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002717 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002718 try:
kelvin8ec71442015-01-15 16:57:00 -08002719 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002720 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002721 if intentsStr is None:
2722 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002723 # Convert to a dictionary
2724 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002725 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002726 for intent in intents:
2727 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002728 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002729 except TypeError:
2730 main.log.exception( self.name + ": Object not as expected" )
2731 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002732 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002733 main.log.error( self.name + ": EOF exception found" )
2734 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002735 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002736 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002737 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002738 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002739
You Wang3c276252016-09-21 15:21:36 -07002740 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002741 """
2742 Determine the number of flow rules for the given device id that are
2743 in the added state
You Wang3c276252016-09-21 15:21:36 -07002744 Params:
2745 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002746 """
2747 try:
You Wang3c276252016-09-21 15:21:36 -07002748 if core:
2749 cmdStr = "flows any " + str( deviceId ) + " | " +\
2750 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2751 else:
2752 cmdStr = "flows any " + str( deviceId ) + " | " +\
2753 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002754 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002755 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002756 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002757 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002758 except AssertionError:
2759 main.log.exception( "" )
2760 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002761 except pexpect.EOF:
2762 main.log.error( self.name + ": EOF exception found" )
2763 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002764 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002765 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002766 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002767 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002768
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002769 def checkFlowAddedCount( self, deviceId, minFlowCount=0, core=False ):
2770 """
2771 Description:
2772 Check whether the number of flow rules for the given device id that
2773 are in ADDED state is bigger than minFlowCount.
2774 Required:
2775 * deviceId: device id to check the number of added flow rules
2776 Optional:
2777 * minFlowCount: the number of flow rules to compare
2778 * core: if True, only check the number of core flows added
2779 Return:
2780 Returns the number of flow rules if it is bigger than minFlowCount,
2781 returns main.FALSE otherwise.
2782 """
2783 count = self.flowAddedCount( deviceId, core )
2784 count = int( count ) if count else 0
2785 return count if (count > minFlowCount) else main.FALSE
2786
kelvin-onlabd3b64892015-01-20 13:26:24 -08002787 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002788 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002789 Use 'devices' function to obtain list of all devices
2790 and parse the result to obtain a list of all device
2791 id's. Returns this list. Returns empty list if no
2792 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002793 List is ordered sequentially
2794
andrewonlab3e15ead2014-10-15 14:21:34 -04002795 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002796 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002797 the ids. By obtaining the list of device ids on the fly,
2798 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002799 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002800 try:
kelvin8ec71442015-01-15 16:57:00 -08002801 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002802 devicesStr = self.devices( jsonFormat=False )
2803 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002804
kelvin-onlabd3b64892015-01-20 13:26:24 -08002805 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002806 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002807 return idList
kelvin8ec71442015-01-15 16:57:00 -08002808
2809 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002810 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002811 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002812 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002813 # Split list further into arguments before and after string
2814 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002815 # append to idList
2816 for arg in tempList:
2817 idList.append( arg.split( "id=" )[ 1 ] )
2818 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002819
Jon Halld4d4b372015-01-28 16:02:41 -08002820 except TypeError:
2821 main.log.exception( self.name + ": Object not as expected" )
2822 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002823 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002824 main.log.error( self.name + ": EOF exception found" )
2825 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002826 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002827 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002828 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002829 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002830
kelvin-onlabd3b64892015-01-20 13:26:24 -08002831 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002832 """
andrewonlab7c211572014-10-15 16:45:20 -04002833 Uses 'nodes' function to obtain list of all nodes
2834 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002835 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002836 Returns:
2837 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002838 """
andrewonlab7c211572014-10-15 16:45:20 -04002839 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002840 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002841 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002842 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002843 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002844 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002845 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002846 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002847 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002848 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002849 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002850 except ( TypeError, ValueError ):
2851 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002852 return None
andrewonlab7c211572014-10-15 16:45:20 -04002853 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002854 main.log.error( self.name + ": EOF exception found" )
2855 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002856 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002857 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002858 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002859 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002860
kelvin-onlabd3b64892015-01-20 13:26:24 -08002861 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002862 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002863 Return the first device from the devices api whose 'id' contains 'dpid'
2864 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002865 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002866 try:
kelvin8ec71442015-01-15 16:57:00 -08002867 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002868 return None
2869 else:
kelvin8ec71442015-01-15 16:57:00 -08002870 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002871 rawDevices = self.devices()
2872 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002873 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002874 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002875 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2876 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002877 return device
2878 return None
Jon Hallc6793552016-01-19 14:18:37 -08002879 except ( TypeError, ValueError ):
2880 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002881 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002882 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002883 main.log.error( self.name + ": EOF exception found" )
2884 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002885 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002886 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002887 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002888 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04002889
You Wang24139872016-05-03 11:48:47 -07002890 def getTopology( self, topologyOutput ):
2891 """
2892 Definition:
2893 Loads a json topology output
2894 Return:
2895 topology = current ONOS topology
2896 """
2897 import json
2898 try:
2899 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002900 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002901 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002902 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002903 except ( TypeError, ValueError ):
2904 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2905 return None
You Wang24139872016-05-03 11:48:47 -07002906 except pexpect.EOF:
2907 main.log.error( self.name + ": EOF exception found" )
2908 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002909 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07002910 except Exception:
2911 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002912 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07002913
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002914 def checkStatus( self, numoswitch, numolink, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002915 """
Jon Hallefbd9792015-03-05 16:11:36 -08002916 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002917 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002918 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002919
Flavio Castro82ee2f62016-06-07 15:04:12 -07002920 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002921 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002922 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002923 logLevel = level to log to.
2924 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002925
Jon Hallefbd9792015-03-05 16:11:36 -08002926 Returns: main.TRUE if the number of switches and links are correct,
2927 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002928 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002929 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002930 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002931 try:
You Wang13310252016-07-31 10:56:14 -07002932 summary = self.summary()
2933 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002934 except ( TypeError, ValueError ):
2935 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2936 return main.ERROR
2937 try:
2938 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07002939 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002940 return main.ERROR
2941 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002942 # Is the number of switches is what we expected
2943 devices = topology.get( 'devices', False )
2944 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002945 nodes = summary.get( 'nodes', False )
2946 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002947 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002948 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002949 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002950 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002951 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2952 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002953 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002954 output = output + "The number of links and switches match "\
2955 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002956 result = main.TRUE
2957 else:
You Wang24139872016-05-03 11:48:47 -07002958 output = output + \
2959 "The number of links and switches does not match " + \
2960 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002961 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002962 output = output + "\n ONOS sees %i devices" % int( devices )
2963 output = output + " (%i expected) " % int( numoswitch )
2964 output = output + "and %i links " % int( links )
2965 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002966 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002967 output = output + "and %i controllers " % int( nodes )
2968 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002969 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002970 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002971 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002972 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002973 else:
You Wang24139872016-05-03 11:48:47 -07002974 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002975 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002976 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002977 main.log.error( self.name + ": EOF exception found" )
2978 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002979 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002980 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002981 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002982 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002983
kelvin-onlabd3b64892015-01-20 13:26:24 -08002984 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002985 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002986 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002987 deviceId must be the id of a device as seen in the onos devices command
2988 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002989 role must be either master, standby, or none
2990
Jon Halle3f39ff2015-01-13 11:50:53 -08002991 Returns:
2992 main.TRUE or main.FALSE based on argument verification and
2993 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002994 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002995 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002996 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002997 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002998 cmdStr = "device-role " +\
2999 str( deviceId ) + " " +\
3000 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003001 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003002 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003003 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003004 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003005 if re.search( "Error", handle ):
3006 # end color output to escape any colours
3007 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003008 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003009 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003010 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003011 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003012 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003013 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003014 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003015 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003016 except AssertionError:
3017 main.log.exception( "" )
3018 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003019 except TypeError:
3020 main.log.exception( self.name + ": Object not as expected" )
3021 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003022 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003023 main.log.error( self.name + ": EOF exception found" )
3024 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003025 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003026 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003027 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003028 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003029
kelvin-onlabd3b64892015-01-20 13:26:24 -08003030 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003031 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003032 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003033 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003034 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003035 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003036 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003037 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003038 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003039 cmdStr += " -j"
3040 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003041 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003042 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003043 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003044 except AssertionError:
3045 main.log.exception( "" )
3046 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003047 except TypeError:
3048 main.log.exception( self.name + ": Object not as expected" )
3049 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003050 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003051 main.log.error( self.name + ": EOF exception found" )
3052 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003053 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003054 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003055 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003056 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003057
kelvin-onlabd3b64892015-01-20 13:26:24 -08003058 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003059 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003060 CLI command to get the current leader for the Election test application
3061 NOTE: Requires installation of the onos-app-election feature
3062 Returns: Node IP of the leader if one exists
3063 None if none exists
3064 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003065 """
Jon Hall94fd0472014-12-08 11:52:42 -08003066 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003067 cmdStr = "election-test-leader"
3068 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003069 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003070 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003071 # Leader
3072 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003073 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003074 nodeSearch = re.search( leaderPattern, response )
3075 if nodeSearch:
3076 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003077 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003078 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003079 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003080 # no leader
3081 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003082 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003083 nullSearch = re.search( nullPattern, response )
3084 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003085 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003086 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003087 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003088 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003089 main.log.error( "Error in electionTestLeader on " + self.name +
3090 ": " + "unexpected response" )
3091 main.log.error( repr( response ) )
3092 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003093 except AssertionError:
3094 main.log.exception( "" )
3095 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003096 except TypeError:
3097 main.log.exception( self.name + ": Object not as expected" )
3098 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003099 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003100 main.log.error( self.name + ": EOF exception found" )
3101 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003102 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003103 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003104 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003105 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003106
kelvin-onlabd3b64892015-01-20 13:26:24 -08003107 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003108 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003109 CLI command to run for leadership of the Election test application.
3110 NOTE: Requires installation of the onos-app-election feature
3111 Returns: Main.TRUE on success
3112 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003113 """
Jon Hall94fd0472014-12-08 11:52:42 -08003114 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003115 cmdStr = "election-test-run"
3116 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003117 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003118 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003119 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003120 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003121 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003122 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003123 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003124 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003125 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003126 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003127 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003128 main.log.error( "Error in electionTestRun on " + self.name +
3129 ": " + "unexpected response" )
3130 main.log.error( repr( response ) )
3131 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003132 except AssertionError:
3133 main.log.exception( "" )
3134 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003135 except TypeError:
3136 main.log.exception( self.name + ": Object not as expected" )
3137 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003138 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003139 main.log.error( self.name + ": EOF exception found" )
3140 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003141 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003142 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003143 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003144 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003145
kelvin-onlabd3b64892015-01-20 13:26:24 -08003146 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003147 """
Jon Hall94fd0472014-12-08 11:52:42 -08003148 * CLI command to withdraw the local node from leadership election for
3149 * the Election test application.
3150 #NOTE: Requires installation of the onos-app-election feature
3151 Returns: Main.TRUE on success
3152 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003153 """
Jon Hall94fd0472014-12-08 11:52:42 -08003154 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003155 cmdStr = "election-test-withdraw"
3156 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003157 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003158 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003159 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003160 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003161 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003162 if re.search( successPattern, response ):
3163 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003164 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003165 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003166 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003167 main.log.error( "Error in electionTestWithdraw on " +
3168 self.name + ": " + "unexpected response" )
3169 main.log.error( repr( response ) )
3170 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003171 except AssertionError:
3172 main.log.exception( "" )
3173 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003174 except TypeError:
3175 main.log.exception( self.name + ": Object not as expected" )
3176 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003177 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003178 main.log.error( self.name + ": EOF exception found" )
3179 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003180 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003181 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003182 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003183 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003184
kelvin8ec71442015-01-15 16:57:00 -08003185 def getDevicePortsEnabledCount( self, dpid ):
3186 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003187 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003188 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003189 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003190 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003191 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3192 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003193 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003194 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003195 if re.search( "No such device", output ):
3196 main.log.error( "Error in getting ports" )
3197 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003198 return output
Jon Hallc6793552016-01-19 14:18:37 -08003199 except AssertionError:
3200 main.log.exception( "" )
3201 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003202 except TypeError:
3203 main.log.exception( self.name + ": Object not as expected" )
3204 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003205 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003206 main.log.error( self.name + ": EOF exception found" )
3207 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003208 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003209 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003210 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003211 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003212
kelvin8ec71442015-01-15 16:57:00 -08003213 def getDeviceLinksActiveCount( self, dpid ):
3214 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003215 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003216 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003217 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003218 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003219 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3220 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003221 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003222 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003223 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003224 main.log.error( "Error in getting ports " )
3225 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003226 return output
Jon Hallc6793552016-01-19 14:18:37 -08003227 except AssertionError:
3228 main.log.exception( "" )
3229 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003230 except TypeError:
3231 main.log.exception( self.name + ": Object not as expected" )
3232 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003233 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003234 main.log.error( self.name + ": EOF exception found" )
3235 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003236 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003237 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003238 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003239 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003240
kelvin8ec71442015-01-15 16:57:00 -08003241 def getAllIntentIds( self ):
3242 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003243 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003244 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003245 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003246 cmdStr = "onos:intents | grep id="
3247 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003248 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003249 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003250 if re.search( "Error", output ):
3251 main.log.error( "Error in getting ports" )
3252 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003253 return output
Jon Hallc6793552016-01-19 14:18:37 -08003254 except AssertionError:
3255 main.log.exception( "" )
3256 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003257 except TypeError:
3258 main.log.exception( self.name + ": Object not as expected" )
3259 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003260 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003261 main.log.error( self.name + ": EOF exception found" )
3262 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003263 main.cleanAndExit()
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!" )
Devin Lim44075962017-08-11 10:56:37 -07003266 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003267
Jon Hall73509952015-02-24 16:42:56 -08003268 def intentSummary( self ):
3269 """
Jon Hallefbd9792015-03-05 16:11:36 -08003270 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003271 """
3272 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003273 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003274 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003275 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003276 states.append( intent.get( 'state', None ) )
3277 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003278 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003279 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003280 except ( TypeError, ValueError ):
3281 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003282 return None
3283 except pexpect.EOF:
3284 main.log.error( self.name + ": EOF exception found" )
3285 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003286 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003287 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003288 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003289 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003290
Jon Hall61282e32015-03-19 11:34:11 -07003291 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003292 """
3293 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003294 Optional argument:
3295 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003296 """
Jon Hall63604932015-02-26 17:09:50 -08003297 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003298 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003299 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003300 cmdStr += " -j"
3301 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003302 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003303 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003304 return output
Jon Hallc6793552016-01-19 14:18:37 -08003305 except AssertionError:
3306 main.log.exception( "" )
3307 return None
Jon Hall63604932015-02-26 17:09:50 -08003308 except TypeError:
3309 main.log.exception( self.name + ": Object not as expected" )
3310 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003311 except pexpect.EOF:
3312 main.log.error( self.name + ": EOF exception found" )
3313 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003314 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003315 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003316 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003317 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003318
acsmarsa4a4d1e2015-07-10 16:01:24 -07003319 def leaderCandidates( self, jsonFormat=True ):
3320 """
3321 Returns the output of the leaders -c command.
3322 Optional argument:
3323 * jsonFormat - boolean indicating if you want output in json
3324 """
3325 try:
3326 cmdStr = "onos:leaders -c"
3327 if jsonFormat:
3328 cmdStr += " -j"
3329 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003330 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003331 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003332 return output
Jon Hallc6793552016-01-19 14:18:37 -08003333 except AssertionError:
3334 main.log.exception( "" )
3335 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003336 except TypeError:
3337 main.log.exception( self.name + ": Object not as expected" )
3338 return None
3339 except pexpect.EOF:
3340 main.log.error( self.name + ": EOF exception found" )
3341 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003342 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003343 except Exception:
3344 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003345 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003346
Jon Hallc6793552016-01-19 14:18:37 -08003347 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003348 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003349 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003350 topic parameter and an empty list if the topic doesn't exist
3351 If no leader is elected leader in the returned list will be "none"
3352 Returns None if there is a type error processing the json object
3353 """
3354 try:
Jon Hall6e709752016-02-01 13:38:46 -08003355 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003356 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003357 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003358 assert "Command not found:" not in rawOutput, rawOutput
3359 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003360 results = []
3361 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003362 if dict[ "topic" ] == topic:
3363 leader = dict[ "leader" ]
3364 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003365 results.append( leader )
3366 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003367 return results
Jon Hallc6793552016-01-19 14:18:37 -08003368 except AssertionError:
3369 main.log.exception( "" )
3370 return None
3371 except ( TypeError, ValueError ):
3372 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003373 return None
3374 except pexpect.EOF:
3375 main.log.error( self.name + ": EOF exception found" )
3376 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003377 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003378 except Exception:
3379 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003380 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003381
Jon Hall61282e32015-03-19 11:34:11 -07003382 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003383 """
3384 Returns the output of the intent Pending map.
3385 """
Jon Hall63604932015-02-26 17:09:50 -08003386 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003387 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003388 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003389 cmdStr += " -j"
3390 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003391 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003392 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003393 return output
Jon Hallc6793552016-01-19 14:18:37 -08003394 except AssertionError:
3395 main.log.exception( "" )
3396 return None
Jon Hall63604932015-02-26 17:09:50 -08003397 except TypeError:
3398 main.log.exception( self.name + ": Object not as expected" )
3399 return None
3400 except pexpect.EOF:
3401 main.log.error( self.name + ": EOF exception found" )
3402 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003403 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003404 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003405 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003406 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003407
Jon Hall2c8959e2016-12-16 12:17:34 -08003408 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003409 """
3410 Returns the output of the raft partitions command for ONOS.
3411 """
Jon Hall61282e32015-03-19 11:34:11 -07003412 # Sample JSON
3413 # {
3414 # "leader": "tcp://10.128.30.11:7238",
3415 # "members": [
3416 # "tcp://10.128.30.11:7238",
3417 # "tcp://10.128.30.17:7238",
3418 # "tcp://10.128.30.13:7238",
3419 # ],
3420 # "name": "p1",
3421 # "term": 3
3422 # },
Jon Hall63604932015-02-26 17:09:50 -08003423 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003424 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003425 if candidates:
3426 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003427 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003428 cmdStr += " -j"
3429 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003430 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003431 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003432 return output
Jon Hallc6793552016-01-19 14:18:37 -08003433 except AssertionError:
3434 main.log.exception( "" )
3435 return None
Jon Hall63604932015-02-26 17:09:50 -08003436 except TypeError:
3437 main.log.exception( self.name + ": Object not as expected" )
3438 return None
3439 except pexpect.EOF:
3440 main.log.error( self.name + ": EOF exception found" )
3441 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003442 main.cleanAndExit()
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!" )
Devin Lim44075962017-08-11 10:56:37 -07003445 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003446
Jon Halle9f909e2016-09-23 10:43:12 -07003447 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003448 """
3449 Returns the output of the apps command for ONOS. This command lists
3450 information about installed ONOS applications
3451 """
3452 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003453 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003454 # "description":"ONOS OpenFlow protocol southbound providers",
3455 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003456 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003457 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003458 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003459 if summary:
3460 cmdStr += " -s"
3461 if active:
3462 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003463 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003464 cmdStr += " -j"
3465 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003466 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003467 assert "Command not found:" not in output, output
3468 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003469 return output
Jon Hallbe379602015-03-24 13:39:32 -07003470 # FIXME: look at specific exceptions/Errors
3471 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003472 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003473 return None
3474 except TypeError:
3475 main.log.exception( self.name + ": Object not as expected" )
3476 return None
3477 except pexpect.EOF:
3478 main.log.error( self.name + ": EOF exception found" )
3479 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003480 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003481 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003482 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003483 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003484
Jon Hall146f1522015-03-24 15:33:24 -07003485 def appStatus( self, appName ):
3486 """
3487 Uses the onos:apps cli command to return the status of an application.
3488 Returns:
3489 "ACTIVE" - If app is installed and activated
3490 "INSTALLED" - If app is installed and deactivated
3491 "UNINSTALLED" - If app is not installed
3492 None - on error
3493 """
Jon Hall146f1522015-03-24 15:33:24 -07003494 try:
3495 if not isinstance( appName, types.StringType ):
3496 main.log.error( self.name + ".appStatus(): appName must be" +
3497 " a string" )
3498 return None
3499 output = self.apps( jsonFormat=True )
3500 appsJson = json.loads( output )
3501 state = None
3502 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003503 if appName == app.get( 'name' ):
3504 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003505 break
3506 if state == "ACTIVE" or state == "INSTALLED":
3507 return state
3508 elif state is None:
Jon Hall8bafdc02017-09-05 11:36:26 -07003509 main.log.warn( "{} app not found", appName )
Jon Hall146f1522015-03-24 15:33:24 -07003510 return "UNINSTALLED"
3511 elif state:
3512 main.log.error( "Unexpected state from 'onos:apps': " +
3513 str( state ) )
3514 return state
Jon Hallc6793552016-01-19 14:18:37 -08003515 except ( TypeError, ValueError ):
3516 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003517 return None
3518 except pexpect.EOF:
3519 main.log.error( self.name + ": EOF exception found" )
3520 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003521 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003522 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003523 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003524 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003525
Jon Hallbe379602015-03-24 13:39:32 -07003526 def app( self, appName, option ):
3527 """
3528 Interacts with the app command for ONOS. This command manages
3529 application inventory.
3530 """
Jon Hallbe379602015-03-24 13:39:32 -07003531 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003532 # Validate argument types
3533 valid = True
3534 if not isinstance( appName, types.StringType ):
3535 main.log.error( self.name + ".app(): appName must be a " +
3536 "string" )
3537 valid = False
3538 if not isinstance( option, types.StringType ):
3539 main.log.error( self.name + ".app(): option must be a string" )
3540 valid = False
3541 if not valid:
3542 return main.FALSE
3543 # Validate Option
3544 option = option.lower()
3545 # NOTE: Install may become a valid option
3546 if option == "activate":
3547 pass
3548 elif option == "deactivate":
3549 pass
3550 elif option == "uninstall":
3551 pass
3552 else:
3553 # Invalid option
3554 main.log.error( "The ONOS app command argument only takes " +
3555 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003556 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003557 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003558 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003559 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003560 assert output is not None, "Error in sendline"
3561 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003562 if "Error executing command" in output:
3563 main.log.error( "Error in processing onos:app command: " +
3564 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003565 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003566 elif "No such application" in output:
3567 main.log.error( "The application '" + appName +
3568 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003569 return main.FALSE
3570 elif "Command not found:" in output:
3571 main.log.error( "Error in processing onos:app command: " +
3572 str( output ) )
3573 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003574 elif "Unsupported command:" in output:
3575 main.log.error( "Incorrect command given to 'app': " +
3576 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003577 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003578 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003579 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003580 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003581 except AssertionError:
3582 main.log.exception( self.name + ": AssertionError exception found" )
3583 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003584 except TypeError:
3585 main.log.exception( self.name + ": Object not as expected" )
3586 return main.ERROR
3587 except pexpect.EOF:
3588 main.log.error( self.name + ": EOF exception found" )
3589 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003590 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003591 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003592 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003593 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003594
Jon Hallbd16b922015-03-26 17:53:15 -07003595 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003596 """
3597 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003598 appName is the hierarchical app name, not the feature name
3599 If check is True, method will check the status of the app after the
3600 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003601 Returns main.TRUE if the command was successfully sent
3602 main.FALSE if the cli responded with an error or given
3603 incorrect input
3604 """
3605 try:
3606 if not isinstance( appName, types.StringType ):
3607 main.log.error( self.name + ".activateApp(): appName must be" +
3608 " a string" )
3609 return main.FALSE
3610 status = self.appStatus( appName )
3611 if status == "INSTALLED":
3612 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003613 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003614 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003615 status = self.appStatus( appName )
3616 if status == "ACTIVE":
3617 return main.TRUE
3618 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003619 main.log.debug( "The state of application " +
3620 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003621 time.sleep( 1 )
3622 return main.FALSE
3623 else: # not 'check' or command didn't succeed
3624 return response
Jon Hall146f1522015-03-24 15:33:24 -07003625 elif status == "ACTIVE":
3626 return main.TRUE
3627 elif status == "UNINSTALLED":
3628 main.log.error( self.name + ": Tried to activate the " +
3629 "application '" + appName + "' which is not " +
3630 "installed." )
3631 else:
3632 main.log.error( "Unexpected return value from appStatus: " +
3633 str( status ) )
3634 return main.ERROR
3635 except TypeError:
3636 main.log.exception( self.name + ": Object not as expected" )
3637 return main.ERROR
3638 except pexpect.EOF:
3639 main.log.error( self.name + ": EOF exception found" )
3640 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003641 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003642 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003643 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003644 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003645
Jon Hallbd16b922015-03-26 17:53:15 -07003646 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003647 """
3648 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003649 appName is the hierarchical app name, not the feature name
3650 If check is True, method will check the status of the app after the
3651 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003652 Returns main.TRUE if the command was successfully sent
3653 main.FALSE if the cli responded with an error or given
3654 incorrect input
3655 """
3656 try:
3657 if not isinstance( appName, types.StringType ):
3658 main.log.error( self.name + ".deactivateApp(): appName must " +
3659 "be a string" )
3660 return main.FALSE
3661 status = self.appStatus( appName )
3662 if status == "INSTALLED":
3663 return main.TRUE
3664 elif status == "ACTIVE":
3665 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003666 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003667 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003668 status = self.appStatus( appName )
3669 if status == "INSTALLED":
3670 return main.TRUE
3671 else:
3672 time.sleep( 1 )
3673 return main.FALSE
3674 else: # not check or command didn't succeed
3675 return response
Jon Hall146f1522015-03-24 15:33:24 -07003676 elif status == "UNINSTALLED":
3677 main.log.warn( self.name + ": Tried to deactivate the " +
3678 "application '" + appName + "' which is not " +
3679 "installed." )
3680 return main.TRUE
3681 else:
3682 main.log.error( "Unexpected return value from appStatus: " +
3683 str( status ) )
3684 return main.ERROR
3685 except TypeError:
3686 main.log.exception( self.name + ": Object not as expected" )
3687 return main.ERROR
3688 except pexpect.EOF:
3689 main.log.error( self.name + ": EOF exception found" )
3690 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003691 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003692 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003693 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003694 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003695
Jon Hallbd16b922015-03-26 17:53:15 -07003696 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003697 """
3698 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003699 appName is the hierarchical app name, not the feature name
3700 If check is True, method will check the status of the app after the
3701 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003702 Returns main.TRUE if the command was successfully sent
3703 main.FALSE if the cli responded with an error or given
3704 incorrect input
3705 """
3706 # TODO: check with Thomas about the state machine for apps
3707 try:
3708 if not isinstance( appName, types.StringType ):
3709 main.log.error( self.name + ".uninstallApp(): appName must " +
3710 "be a string" )
3711 return main.FALSE
3712 status = self.appStatus( appName )
3713 if status == "INSTALLED":
3714 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003715 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003716 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003717 status = self.appStatus( appName )
3718 if status == "UNINSTALLED":
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 == "ACTIVE":
3726 main.log.warn( self.name + ": Tried to uninstall the " +
3727 "application '" + appName + "' which is " +
3728 "currently active." )
3729 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003730 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003731 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003732 status = self.appStatus( appName )
3733 if status == "UNINSTALLED":
3734 return main.TRUE
3735 else:
3736 time.sleep( 1 )
3737 return main.FALSE
3738 else: # not check or command didn't succeed
3739 return response
Jon Hall146f1522015-03-24 15:33:24 -07003740 elif status == "UNINSTALLED":
3741 return main.TRUE
3742 else:
3743 main.log.error( "Unexpected return value from appStatus: " +
3744 str( status ) )
3745 return main.ERROR
3746 except TypeError:
3747 main.log.exception( self.name + ": Object not as expected" )
3748 return main.ERROR
3749 except pexpect.EOF:
3750 main.log.error( self.name + ": EOF exception found" )
3751 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003752 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003753 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003754 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003755 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003756
3757 def appIDs( self, jsonFormat=True ):
3758 """
3759 Show the mappings between app id and app names given by the 'app-ids'
3760 cli command
3761 """
3762 try:
3763 cmdStr = "app-ids"
3764 if jsonFormat:
3765 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003766 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003767 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003768 assert "Command not found:" not in output, output
3769 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003770 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003771 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003772 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003773 return None
3774 except TypeError:
3775 main.log.exception( self.name + ": Object not as expected" )
3776 return None
3777 except pexpect.EOF:
3778 main.log.error( self.name + ": EOF exception found" )
3779 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003780 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003781 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003782 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003783 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003784
3785 def appToIDCheck( self ):
3786 """
3787 This method will check that each application's ID listed in 'apps' is
3788 the same as the ID listed in 'app-ids'. The check will also check that
3789 there are no duplicate IDs issued. Note that an app ID should be
3790 a globaly unique numerical identifier for app/app-like features. Once
3791 an ID is registered, the ID is never freed up so that if an app is
3792 reinstalled it will have the same ID.
3793
3794 Returns: main.TRUE if the check passes and
3795 main.FALSE if the check fails or
3796 main.ERROR if there is some error in processing the test
3797 """
3798 try:
Jon Hall390696c2015-05-05 17:13:41 -07003799 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003800 rawJson = self.appIDs( jsonFormat=True )
3801 if rawJson:
3802 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003803 else:
Jon Hallc6793552016-01-19 14:18:37 -08003804 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003805 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003806 rawJson = self.apps( jsonFormat=True )
3807 if rawJson:
3808 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003809 else:
Jon Hallc6793552016-01-19 14:18:37 -08003810 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003811 bail = True
3812 if bail:
3813 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003814 result = main.TRUE
3815 for app in apps:
3816 appID = app.get( 'id' )
3817 if appID is None:
3818 main.log.error( "Error parsing app: " + str( app ) )
3819 result = main.FALSE
3820 appName = app.get( 'name' )
3821 if appName is None:
3822 main.log.error( "Error parsing app: " + str( app ) )
3823 result = main.FALSE
3824 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003825 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07003826 if not current: # if ids doesn't have this id
3827 result = main.FALSE
3828 main.log.error( "'app-ids' does not have the ID for " +
3829 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08003830 main.log.debug( "apps command returned: " + str( app ) +
3831 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003832 elif len( current ) > 1:
3833 # there is more than one app with this ID
3834 result = main.FALSE
3835 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003836 elif not current[ 0 ][ 'name' ] == appName:
3837 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07003838 result = main.FALSE
3839 main.log.error( "'app-ids' has " + str( currentName ) +
3840 " registered under id:" + str( appID ) +
3841 " but 'apps' has " + str( appName ) )
3842 else:
3843 pass # id and name match!
3844 # now make sure that app-ids has no duplicates
3845 idsList = []
3846 namesList = []
3847 for item in ids:
3848 idsList.append( item[ 'id' ] )
3849 namesList.append( item[ 'name' ] )
3850 if len( idsList ) != len( set( idsList ) ) or\
3851 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003852 main.log.error( "'app-ids' has some duplicate entries: \n"
3853 + json.dumps( ids,
3854 sort_keys=True,
3855 indent=4,
3856 separators=( ',', ': ' ) ) )
3857 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003858 return result
Jon Hallc6793552016-01-19 14:18:37 -08003859 except ( TypeError, ValueError ):
3860 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003861 return main.ERROR
3862 except pexpect.EOF:
3863 main.log.error( self.name + ": EOF exception found" )
3864 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003865 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003866 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003867 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003868 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003869
Jon Hallfb760a02015-04-13 15:35:03 -07003870 def getCfg( self, component=None, propName=None, short=False,
3871 jsonFormat=True ):
3872 """
3873 Get configuration settings from onos cli
3874 Optional arguments:
3875 component - Optionally only list configurations for a specific
3876 component. If None, all components with configurations
3877 are displayed. Case Sensitive string.
3878 propName - If component is specified, propName option will show
3879 only this specific configuration from that component.
3880 Case Sensitive string.
3881 jsonFormat - Returns output as json. Note that this will override
3882 the short option
3883 short - Short, less verbose, version of configurations.
3884 This is overridden by the json option
3885 returns:
3886 Output from cli as a string or None on error
3887 """
3888 try:
3889 baseStr = "cfg"
3890 cmdStr = " get"
3891 componentStr = ""
3892 if component:
3893 componentStr += " " + component
3894 if propName:
3895 componentStr += " " + propName
3896 if jsonFormat:
3897 baseStr += " -j"
3898 elif short:
3899 baseStr += " -s"
3900 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003901 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003902 assert "Command not found:" not in output, output
3903 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003904 return output
3905 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003906 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003907 return None
3908 except TypeError:
3909 main.log.exception( self.name + ": Object not as expected" )
3910 return None
3911 except pexpect.EOF:
3912 main.log.error( self.name + ": EOF exception found" )
3913 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003914 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003915 except Exception:
3916 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003917 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003918
3919 def setCfg( self, component, propName, value=None, check=True ):
3920 """
3921 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003922 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003923 component - The case sensitive name of the component whose
3924 property is to be set
3925 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003926 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003927 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003928 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07003929 check - Boolean, Check whether the option was successfully set this
3930 only applies when a value is given.
3931 returns:
3932 main.TRUE on success or main.FALSE on failure. If check is False,
3933 will return main.TRUE unless there is an error
3934 """
3935 try:
3936 baseStr = "cfg"
3937 cmdStr = " set " + str( component ) + " " + str( propName )
3938 if value is not None:
3939 cmdStr += " " + str( value )
3940 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003941 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003942 assert "Command not found:" not in output, output
3943 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003944 if value and check:
3945 results = self.getCfg( component=str( component ),
3946 propName=str( propName ),
3947 jsonFormat=True )
3948 # Check if current value is what we just set
3949 try:
3950 jsonOutput = json.loads( results )
3951 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003952 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003953 main.log.exception( "Error parsing cfg output" )
3954 main.log.error( "output:" + repr( results ) )
3955 return main.FALSE
3956 if current == str( value ):
3957 return main.TRUE
3958 return main.FALSE
3959 return main.TRUE
3960 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003961 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003962 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003963 except ( TypeError, ValueError ):
3964 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003965 return main.FALSE
3966 except pexpect.EOF:
3967 main.log.error( self.name + ": EOF exception found" )
3968 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003969 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003970 except Exception:
3971 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003972 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003973
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003974 def distPrimitivesSend( self, cmd ):
3975 """
3976 Function to handle sending cli commands for the distributed primitives test app
3977
3978 This command will catch some exceptions and retry the command on some
3979 specific store exceptions.
3980
3981 Required arguments:
3982 cmd - The command to send to the cli
3983 returns:
3984 string containing the cli output
3985 None on Error
3986 """
3987 try:
3988 output = self.sendline( cmd )
3989 try:
3990 assert output is not None, "Error in sendline"
3991 # TODO: Maybe make this less hardcoded
3992 # ConsistentMap Exceptions
3993 assert "org.onosproject.store.service" not in output
3994 # Node not leader
3995 assert "java.lang.IllegalStateException" not in output
3996 except AssertionError:
3997 main.log.error( "Error in processing '" + cmd + "' " +
3998 "command: " + str( output ) )
3999 retryTime = 30 # Conservative time, given by Madan
4000 main.log.info( "Waiting " + str( retryTime ) +
4001 "seconds before retrying." )
4002 time.sleep( retryTime ) # Due to change in mastership
4003 output = self.sendline( cmd )
4004 assert output is not None, "Error in sendline"
4005 assert "Command not found:" not in output, output
4006 assert "Error executing command" not in output, output
4007 main.log.info( self.name + ": " + output )
4008 return output
4009 except AssertionError:
4010 main.log.exception( "Error in processing '" + cmd + "' command." )
4011 return None
4012 except TypeError:
4013 main.log.exception( self.name + ": Object not as expected" )
4014 return None
4015 except pexpect.EOF:
4016 main.log.error( self.name + ": EOF exception found" )
4017 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004018 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004019 except Exception:
4020 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004021 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004022
Jon Hall390696c2015-05-05 17:13:41 -07004023 def setTestAdd( self, setName, values ):
4024 """
4025 CLI command to add elements to a distributed set.
4026 Arguments:
4027 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004028 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004029 Example usages:
4030 setTestAdd( "set1", "a b c" )
4031 setTestAdd( "set2", "1" )
4032 returns:
4033 main.TRUE on success OR
4034 main.FALSE if elements were already in the set OR
4035 main.ERROR on error
4036 """
4037 try:
4038 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004039 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004040 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4041 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004042 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004043 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004044 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004045 return main.FALSE
4046 else:
4047 main.log.error( self.name + ": setTestAdd did not" +
4048 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004049 main.log.debug( self.name + " actual: " + repr( output ) )
4050 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004051 except TypeError:
4052 main.log.exception( self.name + ": Object not as expected" )
4053 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004054 except Exception:
4055 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004056 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004057
4058 def setTestRemove( self, setName, values, clear=False, retain=False ):
4059 """
4060 CLI command to remove elements from a distributed set.
4061 Required arguments:
4062 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004063 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004064 Optional arguments:
4065 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004066 retain - Retain only the given values. (intersection of the
4067 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004068 returns:
4069 main.TRUE on success OR
4070 main.FALSE if the set was not changed OR
4071 main.ERROR on error
4072 """
4073 try:
4074 cmdStr = "set-test-remove "
4075 if clear:
4076 cmdStr += "-c " + str( setName )
4077 elif retain:
4078 cmdStr += "-r " + str( setName ) + " " + str( values )
4079 else:
4080 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004081 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004082 if clear:
4083 pattern = "Set " + str( setName ) + " cleared"
4084 if re.search( pattern, output ):
4085 return main.TRUE
4086 elif retain:
4087 positivePattern = str( setName ) + " was pruned to contain " +\
4088 "only elements of set \[(.*)\]"
4089 negativePattern = str( setName ) + " was not changed by " +\
4090 "retaining only elements of the set " +\
4091 "\[(.*)\]"
4092 if re.search( positivePattern, output ):
4093 return main.TRUE
4094 elif re.search( negativePattern, output ):
4095 return main.FALSE
4096 else:
4097 positivePattern = "\[(.*)\] was removed from the set " +\
4098 str( setName )
4099 if ( len( values.split() ) == 1 ):
4100 negativePattern = "\[(.*)\] was not in set " +\
4101 str( setName )
4102 else:
4103 negativePattern = "No element of \[(.*)\] was in set " +\
4104 str( setName )
4105 if re.search( positivePattern, output ):
4106 return main.TRUE
4107 elif re.search( negativePattern, output ):
4108 return main.FALSE
4109 main.log.error( self.name + ": setTestRemove did not" +
4110 " match expected output" )
4111 main.log.debug( self.name + " expected: " + pattern )
4112 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!" )
Devin Lim44075962017-08-11 10:56:37 -07004119 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004120
4121 def setTestGet( self, setName, values="" ):
4122 """
4123 CLI command to get the elements in a distributed set.
4124 Required arguments:
4125 setName - The name of the set to remove from.
4126 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004127 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004128 returns:
4129 main.ERROR on error OR
4130 A list of elements in the set if no optional arguments are
4131 supplied OR
4132 A tuple containing the list then:
4133 main.FALSE if the given values are not in the set OR
4134 main.TRUE if the given values are in the set OR
4135 """
4136 try:
4137 values = str( values ).strip()
4138 setName = str( setName ).strip()
4139 length = len( values.split() )
4140 containsCheck = None
4141 # Patterns to match
4142 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004143 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004144 containsTrue = "Set " + setName + " contains the value " + values
4145 containsFalse = "Set " + setName + " did not contain the value " +\
4146 values
4147 containsAllTrue = "Set " + setName + " contains the the subset " +\
4148 setPattern
4149 containsAllFalse = "Set " + setName + " did not contain the the" +\
4150 " subset " + setPattern
4151
4152 cmdStr = "set-test-get "
4153 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004154 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004155 if length == 0:
4156 match = re.search( pattern, output )
4157 else: # if given values
4158 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004159 patternTrue = pattern + "\r\n" + containsTrue
4160 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004161 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004162 patternTrue = pattern + "\r\n" + containsAllTrue
4163 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004164 matchTrue = re.search( patternTrue, output )
4165 matchFalse = re.search( patternFalse, output )
4166 if matchTrue:
4167 containsCheck = main.TRUE
4168 match = matchTrue
4169 elif matchFalse:
4170 containsCheck = main.FALSE
4171 match = matchFalse
4172 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004173 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004174 "expected output" )
4175 main.log.debug( self.name + " expected: " + pattern )
4176 main.log.debug( self.name + " actual: " + repr( output ) )
4177 match = None
4178 if match:
4179 setMatch = match.group( 1 )
4180 if setMatch == '':
4181 setList = []
4182 else:
4183 setList = setMatch.split( ", " )
4184 if length > 0:
4185 return ( setList, containsCheck )
4186 else:
4187 return setList
4188 else: # no match
4189 main.log.error( self.name + ": setTestGet did not" +
4190 " match expected output" )
4191 main.log.debug( self.name + " expected: " + pattern )
4192 main.log.debug( self.name + " actual: " + repr( output ) )
4193 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004194 except TypeError:
4195 main.log.exception( self.name + ": Object not as expected" )
4196 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004197 except Exception:
4198 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004199 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004200
4201 def setTestSize( self, setName ):
4202 """
4203 CLI command to get the elements in a distributed set.
4204 Required arguments:
4205 setName - The name of the set to remove from.
4206 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004207 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004208 None on error
4209 """
4210 try:
4211 # TODO: Should this check against the number of elements returned
4212 # and then return true/false based on that?
4213 setName = str( setName ).strip()
4214 # Patterns to match
4215 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004216 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004217 setPattern
4218 cmdStr = "set-test-get -s "
4219 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004220 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004221 match = re.search( pattern, output )
4222 if match:
4223 setSize = int( match.group( 1 ) )
4224 setMatch = match.group( 2 )
4225 if len( setMatch.split() ) == setSize:
4226 main.log.info( "The size returned by " + self.name +
4227 " matches the number of elements in " +
4228 "the returned set" )
4229 else:
4230 main.log.error( "The size returned by " + self.name +
4231 " does not match the number of " +
4232 "elements in the returned set." )
4233 return setSize
4234 else: # no match
4235 main.log.error( self.name + ": setTestGet did not" +
4236 " match expected output" )
4237 main.log.debug( self.name + " expected: " + pattern )
4238 main.log.debug( self.name + " actual: " + repr( output ) )
4239 return None
Jon Hall390696c2015-05-05 17:13:41 -07004240 except TypeError:
4241 main.log.exception( self.name + ": Object not as expected" )
4242 return None
Jon Hall390696c2015-05-05 17:13:41 -07004243 except Exception:
4244 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004245 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004246
Jon Hall80daded2015-05-27 16:07:00 -07004247 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004248 """
4249 Command to list the various counters in the system.
4250 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004251 if jsonFormat, a string of the json object returned by the cli
4252 command
4253 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004254 None on error
4255 """
Jon Hall390696c2015-05-05 17:13:41 -07004256 try:
Jon Hall390696c2015-05-05 17:13:41 -07004257 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004258 if jsonFormat:
4259 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004260 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004261 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004262 assert "Command not found:" not in output, output
4263 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004264 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004265 return output
Jon Hall390696c2015-05-05 17:13:41 -07004266 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004267 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004268 return None
Jon Hall390696c2015-05-05 17:13:41 -07004269 except TypeError:
4270 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004271 return None
Jon Hall390696c2015-05-05 17:13:41 -07004272 except pexpect.EOF:
4273 main.log.error( self.name + ": EOF exception found" )
4274 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004275 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004276 except Exception:
4277 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004278 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004279
Jon Hall935db192016-04-19 00:22:04 -07004280 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004281 """
Jon Halle1a3b752015-07-22 13:02:46 -07004282 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004283 Required arguments:
4284 counter - The name of the counter to increment.
4285 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004286 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004287 returns:
4288 integer value of the counter or
4289 None on Error
4290 """
4291 try:
4292 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004293 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004294 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004295 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004296 if delta != 1:
4297 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004298 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004299 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004300 match = re.search( pattern, output )
4301 if match:
4302 return int( match.group( 1 ) )
4303 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004304 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004305 " match expected output." )
4306 main.log.debug( self.name + " expected: " + pattern )
4307 main.log.debug( self.name + " actual: " + repr( output ) )
4308 return None
Jon Hall390696c2015-05-05 17:13:41 -07004309 except TypeError:
4310 main.log.exception( self.name + ": Object not as expected" )
4311 return None
Jon Hall390696c2015-05-05 17:13:41 -07004312 except Exception:
4313 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004314 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004315
Jon Hall935db192016-04-19 00:22:04 -07004316 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004317 """
4318 CLI command to get a distributed counter then add a delta to it.
4319 Required arguments:
4320 counter - The name of the counter to increment.
4321 Optional arguments:
4322 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004323 returns:
4324 integer value of the counter or
4325 None on Error
4326 """
4327 try:
4328 counter = str( counter )
4329 delta = int( delta )
4330 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004331 cmdStr += counter
4332 if delta != 1:
4333 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004334 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004335 pattern = counter + " was updated to (-?\d+)"
4336 match = re.search( pattern, output )
4337 if match:
4338 return int( match.group( 1 ) )
4339 else:
4340 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4341 " match expected output." )
4342 main.log.debug( self.name + " expected: " + pattern )
4343 main.log.debug( self.name + " actual: " + repr( output ) )
4344 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004345 except TypeError:
4346 main.log.exception( self.name + ": Object not as expected" )
4347 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004348 except Exception:
4349 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004350 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004351
4352 def valueTestGet( self, valueName ):
4353 """
4354 CLI command to get the value of an atomic value.
4355 Required arguments:
4356 valueName - The name of the value to get.
4357 returns:
4358 string value of the value or
4359 None on Error
4360 """
4361 try:
4362 valueName = str( valueName )
4363 cmdStr = "value-test "
4364 operation = "get"
4365 cmdStr = "value-test {} {}".format( valueName,
4366 operation )
4367 output = self.distPrimitivesSend( cmdStr )
4368 pattern = "(\w+)"
4369 match = re.search( pattern, output )
4370 if match:
4371 return match.group( 1 )
4372 else:
4373 main.log.error( self.name + ": valueTestGet did not" +
4374 " match expected output." )
4375 main.log.debug( self.name + " expected: " + pattern )
4376 main.log.debug( self.name + " actual: " + repr( output ) )
4377 return None
4378 except TypeError:
4379 main.log.exception( self.name + ": Object not as expected" )
4380 return None
4381 except Exception:
4382 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004383 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004384
4385 def valueTestSet( self, valueName, newValue ):
4386 """
4387 CLI command to set the value of an atomic value.
4388 Required arguments:
4389 valueName - The name of the value to set.
4390 newValue - The value to assign to the given value.
4391 returns:
4392 main.TRUE on success or
4393 main.ERROR on Error
4394 """
4395 try:
4396 valueName = str( valueName )
4397 newValue = str( newValue )
4398 operation = "set"
4399 cmdStr = "value-test {} {} {}".format( valueName,
4400 operation,
4401 newValue )
4402 output = self.distPrimitivesSend( cmdStr )
4403 if output is not None:
4404 return main.TRUE
4405 else:
4406 return main.ERROR
4407 except TypeError:
4408 main.log.exception( self.name + ": Object not as expected" )
4409 return main.ERROR
4410 except Exception:
4411 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004412 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004413
4414 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4415 """
4416 CLI command to compareAndSet the value of an atomic value.
4417 Required arguments:
4418 valueName - The name of the value.
4419 oldValue - Compare the current value of the atomic value to this
4420 newValue - If the value equals oldValue, set the value to newValue
4421 returns:
4422 main.TRUE on success or
4423 main.FALSE on failure or
4424 main.ERROR on Error
4425 """
4426 try:
4427 valueName = str( valueName )
4428 oldValue = str( oldValue )
4429 newValue = str( newValue )
4430 operation = "compareAndSet"
4431 cmdStr = "value-test {} {} {} {}".format( valueName,
4432 operation,
4433 oldValue,
4434 newValue )
4435 output = self.distPrimitivesSend( cmdStr )
4436 pattern = "(\w+)"
4437 match = re.search( pattern, output )
4438 if match:
4439 result = match.group( 1 )
4440 if result == "true":
4441 return main.TRUE
4442 elif result == "false":
4443 return main.FALSE
4444 else:
4445 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4446 " match expected output." )
4447 main.log.debug( self.name + " expected: " + pattern )
4448 main.log.debug( self.name + " actual: " + repr( output ) )
4449 return main.ERROR
4450 except TypeError:
4451 main.log.exception( self.name + ": Object not as expected" )
4452 return main.ERROR
4453 except Exception:
4454 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004455 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004456
4457 def valueTestGetAndSet( self, valueName, newValue ):
4458 """
4459 CLI command to getAndSet the value of an atomic value.
4460 Required arguments:
4461 valueName - The name of the value to get.
4462 newValue - The value to assign to the given value
4463 returns:
4464 string value of the value or
4465 None on Error
4466 """
4467 try:
4468 valueName = str( valueName )
4469 cmdStr = "value-test "
4470 operation = "getAndSet"
4471 cmdStr += valueName + " " + operation
4472 cmdStr = "value-test {} {} {}".format( valueName,
4473 operation,
4474 newValue )
4475 output = self.distPrimitivesSend( cmdStr )
4476 pattern = "(\w+)"
4477 match = re.search( pattern, output )
4478 if match:
4479 return match.group( 1 )
4480 else:
4481 main.log.error( self.name + ": valueTestGetAndSet did not" +
4482 " match expected output." )
4483 main.log.debug( self.name + " expected: " + pattern )
4484 main.log.debug( self.name + " actual: " + repr( output ) )
4485 return None
4486 except TypeError:
4487 main.log.exception( self.name + ": Object not as expected" )
4488 return None
4489 except Exception:
4490 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004491 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004492
4493 def valueTestDestroy( self, valueName ):
4494 """
4495 CLI command to destroy an atomic value.
4496 Required arguments:
4497 valueName - The name of the value to destroy.
4498 returns:
4499 main.TRUE on success or
4500 main.ERROR on Error
4501 """
4502 try:
4503 valueName = str( valueName )
4504 cmdStr = "value-test "
4505 operation = "destroy"
4506 cmdStr += valueName + " " + operation
4507 output = self.distPrimitivesSend( cmdStr )
4508 if output is not None:
4509 return main.TRUE
4510 else:
4511 return main.ERROR
4512 except TypeError:
4513 main.log.exception( self.name + ": Object not as expected" )
4514 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004515 except Exception:
4516 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004517 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004518
YPZhangfebf7302016-05-24 16:45:56 -07004519 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004520 """
4521 Description: Execute summary command in onos
4522 Returns: json object ( summary -j ), returns main.FALSE if there is
4523 no output
4524
4525 """
4526 try:
4527 cmdStr = "summary"
4528 if jsonFormat:
4529 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004530 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004531 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004532 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004533 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004534 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004535 if not handle:
4536 main.log.error( self.name + ": There is no output in " +
4537 "summary command" )
4538 return main.FALSE
4539 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004540 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004541 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004542 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004543 except TypeError:
4544 main.log.exception( self.name + ": Object not as expected" )
4545 return None
4546 except pexpect.EOF:
4547 main.log.error( self.name + ": EOF exception found" )
4548 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004549 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004550 except Exception:
4551 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004552 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004553
Jon Hall935db192016-04-19 00:22:04 -07004554 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004555 """
4556 CLI command to get the value of a key in a consistent map using
4557 transactions. This a test function and can only get keys from the
4558 test map hard coded into the cli command
4559 Required arguments:
4560 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004561 returns:
4562 The string value of the key or
4563 None on Error
4564 """
4565 try:
4566 keyName = str( keyName )
4567 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004568 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004569 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004570 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4571 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004572 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004573 return None
4574 else:
4575 match = re.search( pattern, output )
4576 if match:
4577 return match.groupdict()[ 'value' ]
4578 else:
4579 main.log.error( self.name + ": transactionlMapGet did not" +
4580 " match expected output." )
4581 main.log.debug( self.name + " expected: " + pattern )
4582 main.log.debug( self.name + " actual: " + repr( output ) )
4583 return None
4584 except TypeError:
4585 main.log.exception( self.name + ": Object not as expected" )
4586 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004587 except Exception:
4588 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004589 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004590
Jon Hall935db192016-04-19 00:22:04 -07004591 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004592 """
4593 CLI command to put a value into 'numKeys' number of keys in a
4594 consistent map using transactions. This a test function and can only
4595 put into keys named 'Key#' of the test map hard coded into the cli command
4596 Required arguments:
4597 numKeys - Number of keys to add the value to
4598 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004599 returns:
4600 A dictionary whose keys are the name of the keys put into the map
4601 and the values of the keys are dictionaries whose key-values are
4602 'value': value put into map and optionaly
4603 'oldValue': Previous value in the key or
4604 None on Error
4605
4606 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004607 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4608 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004609 """
4610 try:
4611 numKeys = str( numKeys )
4612 value = str( value )
4613 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004614 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004615 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004616 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4617 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4618 results = {}
4619 for line in output.splitlines():
4620 new = re.search( newPattern, line )
4621 updated = re.search( updatedPattern, line )
4622 if new:
4623 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4624 elif updated:
4625 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004626 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004627 else:
4628 main.log.error( self.name + ": transactionlMapGet did not" +
4629 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004630 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4631 newPattern,
4632 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004633 main.log.debug( self.name + " actual: " + repr( output ) )
4634 return results
4635 except TypeError:
4636 main.log.exception( self.name + ": Object not as expected" )
4637 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004638 except Exception:
4639 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004640 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004641
acsmarsdaea66c2015-09-03 11:44:06 -07004642 def maps( self, jsonFormat=True ):
4643 """
4644 Description: Returns result of onos:maps
4645 Optional:
4646 * jsonFormat: enable json formatting of output
4647 """
4648 try:
4649 cmdStr = "maps"
4650 if jsonFormat:
4651 cmdStr += " -j"
4652 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004653 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004654 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004655 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004656 except AssertionError:
4657 main.log.exception( "" )
4658 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004659 except TypeError:
4660 main.log.exception( self.name + ": Object not as expected" )
4661 return None
4662 except pexpect.EOF:
4663 main.log.error( self.name + ": EOF exception found" )
4664 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004665 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004666 except Exception:
4667 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004668 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004669
4670 def getSwController( self, uri, jsonFormat=True ):
4671 """
4672 Descrition: Gets the controller information from the device
4673 """
4674 try:
4675 cmd = "device-controllers "
4676 if jsonFormat:
4677 cmd += "-j "
4678 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004679 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004680 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004681 return response
Jon Hallc6793552016-01-19 14:18:37 -08004682 except AssertionError:
4683 main.log.exception( "" )
4684 return None
GlennRC050596c2015-11-18 17:06:41 -08004685 except TypeError:
4686 main.log.exception( self.name + ": Object not as expected" )
4687 return None
4688 except pexpect.EOF:
4689 main.log.error( self.name + ": EOF exception found" )
4690 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004691 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004692 except Exception:
4693 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004694 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004695
4696 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4697 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004698 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004699
4700 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004701 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08004702 ip - String or List: The ip address of the controller.
4703 This parameter can be formed in a couple of different ways.
4704 VALID:
4705 10.0.0.1 - just the ip address
4706 tcp:10.0.0.1 - the protocol and the ip address
4707 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4708 so that you can add controllers with different
4709 protocols and ports
4710 INVALID:
4711 10.0.0.1:6653 - this is not supported by ONOS
4712
4713 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4714 port - The port number.
4715 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4716
4717 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4718 """
4719 try:
4720 cmd = "device-setcontrollers"
4721
4722 if jsonFormat:
4723 cmd += " -j"
4724 cmd += " " + uri
4725 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004726 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08004727 for item in ip:
4728 if ":" in item:
4729 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004730 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08004731 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004732 elif "." in sitem[ 1 ]:
4733 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08004734 else:
4735 main.log.error( "Malformed entry: " + item )
4736 raise TypeError
4737 else:
4738 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004739 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004740 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004741 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004742 if "Error" in response:
4743 main.log.error( response )
4744 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004745 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004746 except AssertionError:
4747 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004748 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004749 except TypeError:
4750 main.log.exception( self.name + ": Object not as expected" )
4751 return main.FALSE
4752 except pexpect.EOF:
4753 main.log.error( self.name + ": EOF exception found" )
4754 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004755 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004756 except Exception:
4757 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004758 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004759
4760 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004761 '''
GlennRC20fc6522015-12-23 23:26:57 -08004762 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004763 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08004764 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004765 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08004766 Returns:
4767 Returns main.FALSE if an exception is thrown or an error is present
4768 in the response. Otherwise, returns main.TRUE.
4769 NOTE:
4770 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004771 '''
GlennRC20fc6522015-12-23 23:26:57 -08004772 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004773 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07004774 deviceStr = device
4775 device = []
4776 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004777
4778 for d in device:
4779 time.sleep( 1 )
4780 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004781 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004782 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004783 if "Error" in response:
4784 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4785 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004786 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004787 except AssertionError:
4788 main.log.exception( "" )
4789 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004790 except TypeError:
4791 main.log.exception( self.name + ": Object not as expected" )
4792 return main.FALSE
4793 except pexpect.EOF:
4794 main.log.error( self.name + ": EOF exception found" )
4795 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004796 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004797 except Exception:
4798 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004799 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004800
4801 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004802 '''
GlennRC20fc6522015-12-23 23:26:57 -08004803 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004804 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08004805 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004806 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08004807 Returns:
4808 Returns main.FALSE if an exception is thrown or an error is present
4809 in the response. Otherwise, returns main.TRUE.
4810 NOTE:
4811 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004812 '''
GlennRC20fc6522015-12-23 23:26:57 -08004813 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004814 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08004815 host = list( host )
4816
4817 for h in host:
4818 time.sleep( 1 )
4819 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004820 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004821 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004822 if "Error" in response:
4823 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4824 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004825 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004826 except AssertionError:
4827 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004828 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004829 except TypeError:
4830 main.log.exception( self.name + ": Object not as expected" )
4831 return main.FALSE
4832 except pexpect.EOF:
4833 main.log.error( self.name + ": EOF exception found" )
4834 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004835 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004836 except Exception:
4837 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004838 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004839
YPZhangfebf7302016-05-24 16:45:56 -07004840 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004841 '''
GlennRCed771242016-01-13 17:02:47 -08004842 Description:
4843 Bring link down or up in the null-provider.
4844 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004845 begin - (string) One end of a device or switch.
4846 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08004847 returns:
4848 main.TRUE if no exceptions were thrown and no Errors are
4849 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004850 '''
GlennRCed771242016-01-13 17:02:47 -08004851 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004852 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004853 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004854 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004855 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004856 if "Error" in response or "Failure" in response:
4857 main.log.error( response )
4858 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004859 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004860 except AssertionError:
4861 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004862 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004863 except TypeError:
4864 main.log.exception( self.name + ": Object not as expected" )
4865 return main.FALSE
4866 except pexpect.EOF:
4867 main.log.error( self.name + ": EOF exception found" )
4868 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004869 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004870 except Exception:
4871 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004872 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004873
Jon Hall2c8959e2016-12-16 12:17:34 -08004874 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004875 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07004876 Description:
4877 Changes the state of port in an OF switch by means of the
4878 PORTSTATUS OF messages.
4879 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004880 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
4881 port - (string) target port in the device. Ex: '2'
4882 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07004883 returns:
4884 main.TRUE if no exceptions were thrown and no Errors are
4885 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004886 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07004887 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08004888 state = state.lower()
4889 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07004890 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004891 response = self.sendline( cmd, showResponse=True )
4892 assert response is not None, "Error in sendline"
4893 assert "Command not found:" not in response, response
4894 if "Error" in response or "Failure" in response:
4895 main.log.error( response )
4896 return main.FALSE
4897 return main.TRUE
4898 except AssertionError:
4899 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004900 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07004901 except TypeError:
4902 main.log.exception( self.name + ": Object not as expected" )
4903 return main.FALSE
4904 except pexpect.EOF:
4905 main.log.error( self.name + ": EOF exception found" )
4906 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004907 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004908 except Exception:
4909 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004910 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004911
4912 def logSet( self, level="INFO", app="org.onosproject" ):
4913 """
4914 Set the logging level to lvl for a specific app
4915 returns main.TRUE on success
4916 returns main.FALSE if Error occurred
4917 if noExit is True, TestON will not exit, but clean up
4918 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4919 Level defaults to INFO
4920 """
4921 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004922 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004923 self.handle.expect( "onos>" )
4924
4925 response = self.handle.before
4926 if re.search( "Error", response ):
4927 return main.FALSE
4928 return main.TRUE
4929 except pexpect.TIMEOUT:
4930 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07004931 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004932 except pexpect.EOF:
4933 main.log.error( self.name + ": EOF exception found" )
4934 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004935 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004936 except Exception:
4937 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004938 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004939
4940 def getGraphDict( self, timeout=60, includeHost=False ):
4941 """
4942 Return a dictionary which describes the latest network topology data as a
4943 graph.
4944 An example of the dictionary:
4945 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4946 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4947 Each vertex should at least have an 'edges' attribute which describes the
4948 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004949 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07004950 list of attributes.
4951 An example of the edges dictionary:
4952 'edges': { vertex2: { 'port': ..., 'weight': ... },
4953 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004954 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07004955 in topology data.
4956 """
4957 graphDict = {}
4958 try:
4959 links = self.links()
4960 links = json.loads( links )
4961 devices = self.devices()
4962 devices = json.loads( devices )
4963 idToDevice = {}
4964 for device in devices:
4965 idToDevice[ device[ 'id' ] ] = device
4966 if includeHost:
4967 hosts = self.hosts()
4968 # FIXME: support 'includeHost' argument
4969 for link in links:
4970 nodeA = link[ 'src' ][ 'device' ]
4971 nodeB = link[ 'dst' ][ 'device' ]
4972 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07004973 if nodeA not in graphDict.keys():
4974 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004975 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07004976 'type': idToDevice[ nodeA ][ 'type' ],
4977 'available': idToDevice[ nodeA ][ 'available' ],
4978 'role': idToDevice[ nodeA ][ 'role' ],
4979 'mfr': idToDevice[ nodeA ][ 'mfr' ],
4980 'hw': idToDevice[ nodeA ][ 'hw' ],
4981 'sw': idToDevice[ nodeA ][ 'sw' ],
4982 'serial': idToDevice[ nodeA ][ 'serial' ],
4983 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004984 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07004985 else:
4986 # Assert nodeB is not connected to any current links of nodeA
4987 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07004988 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
4989 'type': link[ 'type' ],
4990 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07004991 return graphDict
4992 except ( TypeError, ValueError ):
4993 main.log.exception( self.name + ": Object not as expected" )
4994 return None
4995 except KeyError:
4996 main.log.exception( self.name + ": KeyError exception found" )
4997 return None
4998 except AssertionError:
4999 main.log.exception( self.name + ": AssertionError exception found" )
5000 return None
5001 except pexpect.EOF:
5002 main.log.error( self.name + ": EOF exception found" )
5003 main.log.error( self.name + ": " + self.handle.before )
5004 return None
5005 except Exception:
5006 main.log.exception( self.name + ": Uncaught exception!" )
5007 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005008
5009 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005010 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005011 Send command to check intent-perf summary
5012 Returns: dictionary for intent-perf summary
5013 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005014 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005015 cmd = "intent-perf -s"
5016 respDic = {}
5017 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005018 assert resp is not None, "Error in sendline"
5019 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005020 try:
5021 # Generate the dictionary to return
5022 for l in resp.split( "\n" ):
5023 # Delete any white space in line
5024 temp = re.sub( r'\s+', '', l )
5025 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005026 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005027
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005028 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005029 main.log.exception( self.name + ": Object not as expected" )
5030 return None
5031 except KeyError:
5032 main.log.exception( self.name + ": KeyError exception found" )
5033 return None
5034 except AssertionError:
5035 main.log.exception( self.name + ": AssertionError exception found" )
5036 return None
5037 except pexpect.EOF:
5038 main.log.error( self.name + ": EOF exception found" )
5039 main.log.error( self.name + ": " + self.handle.before )
5040 return None
5041 except Exception:
5042 main.log.exception( self.name + ": Uncaught exception!" )
5043 return None
5044 return respDic
5045
Chiyu Chengec63bde2016-11-17 18:11:36 -08005046 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005047 """
5048 Searches the latest ONOS log file for the given search term and
5049 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005050
chengchiyu08303a02016-09-08 17:40:26 -07005051 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005052 searchTerm:
5053 The string to grep from the ONOS log.
5054 startLine:
5055 The term that decides which line is the start to search the searchTerm in
5056 the karaf log. For now, startTerm only works in 'first' mode.
5057 logNum:
5058 In some extreme cases, one karaf log is not big enough to contain all the
5059 information.Because of this, search mutiply logs is necessary to capture
5060 the right result. logNum is the number of karaf logs that we need to search
5061 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005062 mode:
5063 all: return all the strings that contain the search term
5064 last: return the last string that contains the search term
5065 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005066 num: return the number of times that the searchTerm appears in the log
5067 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005068 """
5069 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005070 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005071 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005072 logPath = '/opt/onos/log/karaf.log.'
5073 logPaths = '/opt/onos/log/karaf.log'
5074 for i in range( 1, logNum ):
5075 logPaths = logPath + str( i ) + " " + logPaths
5076 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005077 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005078 # 100000000 is just a extreme large number to make sure this function can
5079 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005080 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005081 if mode == 'all':
5082 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005083 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005084 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005085 elif mode == 'first':
5086 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5087 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005088 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005089 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005090 return num
You Wang6d301d42017-04-21 10:49:33 -07005091 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005092 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005093 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005094 else:
5095 main.log.error( self.name + " unsupported mode" )
5096 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005097 before = self.sendline( cmd )
5098 before = before.splitlines()
5099 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005100 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005101 return returnLines
5102 except AssertionError:
5103 main.log.error( self.name + " searchTerm is not string type" )
5104 return None
5105 except pexpect.EOF:
5106 main.log.error( self.name + ": EOF exception found" )
5107 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005108 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005109 except pexpect.TIMEOUT:
5110 main.log.error( self.name + ": TIMEOUT exception found" )
5111 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005112 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005113 except Exception:
5114 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005115 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005116
5117 def vplsShow( self, jsonFormat=True ):
5118 """
5119 Description: Returns result of onos:vpls show, which should list the
5120 configured VPLS networks and the assigned interfaces.
5121 Optional:
5122 * jsonFormat: enable json formatting of output
5123 Returns:
5124 The output of the command or None on error.
5125 """
5126 try:
5127 cmdStr = "vpls show"
5128 if jsonFormat:
5129 raise NotImplementedError
5130 cmdStr += " -j"
5131 handle = self.sendline( cmdStr )
5132 assert handle is not None, "Error in sendline"
5133 assert "Command not found:" not in handle, handle
5134 return handle
5135 except AssertionError:
5136 main.log.exception( "" )
5137 return None
5138 except TypeError:
5139 main.log.exception( self.name + ": Object not as expected" )
5140 return None
5141 except pexpect.EOF:
5142 main.log.error( self.name + ": EOF exception found" )
5143 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005144 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005145 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005146 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005147 return None
5148 except Exception:
5149 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005150 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005151
5152 def parseVplsShow( self ):
5153 """
5154 Parse the cli output of 'vpls show' into json output. This is required
5155 as there is currently no json output available.
5156 """
5157 try:
5158 output = []
5159 raw = self.vplsShow( jsonFormat=False )
5160 namePat = "VPLS name: (?P<name>\w+)"
5161 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5162 encapPat = "Encapsulation: (?P<encap>\w+)"
5163 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5164 mIter = re.finditer( pattern, raw )
5165 for match in mIter:
5166 item = {}
5167 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005168 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005169 if ifaces == [ "" ]:
5170 ifaces = []
5171 item[ 'interfaces' ] = ifaces
5172 encap = match.group( 'encap' )
5173 if encap != 'NONE':
5174 item[ 'encapsulation' ] = encap.lower()
5175 output.append( item )
5176 return output
5177 except Exception:
5178 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005179 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005180
5181 def vplsList( self, jsonFormat=True ):
5182 """
5183 Description: Returns result of onos:vpls list, which should list the
5184 configured VPLS networks.
5185 Optional:
5186 * jsonFormat: enable json formatting of output
5187 """
5188 try:
5189 cmdStr = "vpls list"
5190 if jsonFormat:
5191 raise NotImplementedError
5192 cmdStr += " -j"
5193 handle = self.sendline( cmdStr )
5194 assert handle is not None, "Error in sendline"
5195 assert "Command not found:" not in handle, handle
5196 return handle
5197 except AssertionError:
5198 main.log.exception( "" )
5199 return None
5200 except TypeError:
5201 main.log.exception( self.name + ": Object not as expected" )
5202 return None
5203 except pexpect.EOF:
5204 main.log.error( self.name + ": EOF exception found" )
5205 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005206 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005207 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005208 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005209 return None
5210 except Exception:
5211 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005212 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005213
5214 def vplsCreate( self, network ):
5215 """
5216 CLI command to create a new VPLS network.
5217 Required arguments:
5218 network - String name of the network to create.
5219 returns:
5220 main.TRUE on success and main.FALSE on failure
5221 """
5222 try:
5223 network = str( network )
5224 cmdStr = "vpls create "
5225 cmdStr += network
5226 output = self.sendline( cmdStr )
5227 assert output is not None, "Error in sendline"
5228 assert "Command not found:" not in output, output
5229 assert "Error executing command" not in output, output
5230 assert "VPLS already exists:" not in output, output
5231 return main.TRUE
5232 except AssertionError:
5233 main.log.exception( "" )
5234 return main.FALSE
5235 except TypeError:
5236 main.log.exception( self.name + ": Object not as expected" )
5237 return main.FALSE
5238 except pexpect.EOF:
5239 main.log.error( self.name + ": EOF exception found" )
5240 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005241 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005242 except Exception:
5243 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005244 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005245
5246 def vplsDelete( self, network ):
5247 """
5248 CLI command to delete a VPLS network.
5249 Required arguments:
5250 network - Name of the network to delete.
5251 returns:
5252 main.TRUE on success and main.FALSE on failure
5253 """
5254 try:
5255 network = str( network )
5256 cmdStr = "vpls delete "
5257 cmdStr += network
5258 output = self.sendline( cmdStr )
5259 assert output is not None, "Error in sendline"
5260 assert "Command not found:" not in output, output
5261 assert "Error executing command" not in output, output
5262 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005263 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005264 return main.TRUE
5265 except AssertionError:
5266 main.log.exception( "" )
5267 return main.FALSE
5268 except TypeError:
5269 main.log.exception( self.name + ": Object not as expected" )
5270 return main.FALSE
5271 except pexpect.EOF:
5272 main.log.error( self.name + ": EOF exception found" )
5273 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005274 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005275 except Exception:
5276 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005277 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005278
5279 def vplsAddIface( self, network, iface ):
5280 """
5281 CLI command to add an interface to a VPLS network.
5282 Required arguments:
5283 network - Name of the network to add the interface to.
5284 iface - The ONOS name for an interface.
5285 returns:
5286 main.TRUE on success and main.FALSE on failure
5287 """
5288 try:
5289 network = str( network )
5290 iface = str( iface )
5291 cmdStr = "vpls add-if "
5292 cmdStr += network + " " + iface
5293 output = self.sendline( cmdStr )
5294 assert output is not None, "Error in sendline"
5295 assert "Command not found:" not in output, output
5296 assert "Error executing command" not in output, output
5297 assert "already associated to network" not in output, output
5298 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005299 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005300 return main.TRUE
5301 except AssertionError:
5302 main.log.exception( "" )
5303 return main.FALSE
5304 except TypeError:
5305 main.log.exception( self.name + ": Object not as expected" )
5306 return main.FALSE
5307 except pexpect.EOF:
5308 main.log.error( self.name + ": EOF exception found" )
5309 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005310 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005311 except Exception:
5312 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005313 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005314
5315 def vplsRemIface( self, network, iface ):
5316 """
5317 CLI command to remove an interface from a VPLS network.
5318 Required arguments:
5319 network - Name of the network to remove the interface from.
5320 iface - Name of the interface to remove.
5321 returns:
5322 main.TRUE on success and main.FALSE on failure
5323 """
5324 try:
5325 iface = str( iface )
5326 cmdStr = "vpls rem-if "
5327 cmdStr += network + " " + iface
5328 output = self.sendline( cmdStr )
5329 assert output is not None, "Error in sendline"
5330 assert "Command not found:" not in output, output
5331 assert "Error executing command" not in output, output
5332 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005333 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005334 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 )
Devin Lim44075962017-08-11 10:56:37 -07005344 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005345 except Exception:
5346 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005347 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005348
5349 def vplsClean( self ):
5350 """
5351 Description: Clears the VPLS app configuration.
5352 Returns: main.TRUE on success and main.FALSE on failure
5353 """
5354 try:
5355 cmdStr = "vpls clean"
5356 handle = self.sendline( cmdStr )
5357 assert handle is not None, "Error in sendline"
5358 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005359 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005360 return handle
5361 except AssertionError:
5362 main.log.exception( "" )
5363 return main.FALSE
5364 except TypeError:
5365 main.log.exception( self.name + ": Object not as expected" )
5366 return main.FALSE
5367 except pexpect.EOF:
5368 main.log.error( self.name + ": EOF exception found" )
5369 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005370 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005371 except Exception:
5372 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005373 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005374
5375 def vplsSetEncap( self, network, encapType ):
5376 """
5377 CLI command to add an interface to a VPLS network.
5378 Required arguments:
5379 network - Name of the network to create.
5380 encapType - Type of encapsulation.
5381 returns:
5382 main.TRUE on success and main.FALSE on failure
5383 """
5384 try:
5385 network = str( network )
5386 encapType = str( encapType ).upper()
5387 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5388 cmdStr = "vpls set-encap "
5389 cmdStr += network + " " + encapType
5390 output = self.sendline( cmdStr )
5391 assert output is not None, "Error in sendline"
5392 assert "Command not found:" not in output, output
5393 assert "Error executing command" not in output, output
5394 assert "already associated to network" not in output, output
5395 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005396 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005397 return main.TRUE
5398 except AssertionError:
5399 main.log.exception( "" )
5400 return main.FALSE
5401 except TypeError:
5402 main.log.exception( self.name + ": Object not as expected" )
5403 return main.FALSE
5404 except pexpect.EOF:
5405 main.log.error( self.name + ": EOF exception found" )
5406 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005407 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005408 except Exception:
5409 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005410 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005411
5412 def interfaces( self, jsonFormat=True ):
5413 """
5414 Description: Returns result of interfaces command.
5415 Optional:
5416 * jsonFormat: enable json formatting of output
5417 Returns:
5418 The output of the command or None on error.
5419 """
5420 try:
5421 cmdStr = "interfaces"
5422 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005423 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005424 cmdStr += " -j"
5425 handle = self.sendline( cmdStr )
5426 assert handle is not None, "Error in sendline"
5427 assert "Command not found:" not in handle, handle
5428 return handle
5429 except AssertionError:
5430 main.log.exception( "" )
5431 return None
5432 except TypeError:
5433 main.log.exception( self.name + ": Object not as expected" )
5434 return None
5435 except pexpect.EOF:
5436 main.log.error( self.name + ": EOF exception found" )
5437 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005438 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005439 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005440 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005441 return None
5442 except Exception:
5443 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005444 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005445
5446 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005447 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005448 Get the timestamp of searchTerm from karaf log.
5449
5450 Arguments:
5451 splitTerm_before and splitTerm_after:
5452
5453 The terms that split the string that contains the timeStamp of
5454 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5455 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5456 and the splitTerm_after is "x"
5457
5458 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005459 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005460 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005461 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005462 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005463 return main.ERROR
5464 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005465 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005466 main.log.warn( "Captured timestamp string is empty" )
5467 return main.ERROR
5468 lines = lines[ 0 ]
5469 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005470 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005471 # get the target value
5472 line = lines.split( splitTerm_before )
5473 key = line[ 1 ].split( splitTerm_after )
5474 return int( key[ 0 ] )
5475 except IndexError:
5476 main.log.warn( "Index Error!" )
5477 return main.ERROR
5478 except AssertionError:
5479 main.log.warn( "Search Term Not Found " )
5480 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005481
5482 def workQueueAdd( self, queueName, value ):
5483 """
5484 CLI command to add a string to the specified Work Queue.
5485 This function uses the distributed primitives test app, which
5486 gives some cli access to distributed primitives for testing
5487 purposes only.
5488
5489 Required arguments:
5490 queueName - The name of the queue to add to
5491 value - The value to add to the queue
5492 returns:
5493 main.TRUE on success, main.FALSE on failure and
5494 main.ERROR on error.
5495 """
5496 try:
5497 queueName = str( queueName )
5498 value = str( value )
5499 prefix = "work-queue-test"
5500 operation = "add"
5501 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5502 output = self.distPrimitivesSend( cmdStr )
5503 if "Invalid operation name" in output:
5504 main.log.warn( output )
5505 return main.ERROR
5506 elif "Done" in output:
5507 return main.TRUE
5508 except TypeError:
5509 main.log.exception( self.name + ": Object not as expected" )
5510 return main.ERROR
5511 except Exception:
5512 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005513 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005514
5515 def workQueueAddMultiple( self, queueName, value1, value2 ):
5516 """
5517 CLI command to add two strings to the specified Work Queue.
5518 This function uses the distributed primitives test app, which
5519 gives some cli access to distributed primitives for testing
5520 purposes only.
5521
5522 Required arguments:
5523 queueName - The name of the queue to add to
5524 value1 - The first value to add to the queue
5525 value2 - The second value to add to the queue
5526 returns:
5527 main.TRUE on success, main.FALSE on failure and
5528 main.ERROR on error.
5529 """
5530 try:
5531 queueName = str( queueName )
5532 value1 = str( value1 )
5533 value2 = str( value2 )
5534 prefix = "work-queue-test"
5535 operation = "addMultiple"
5536 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5537 output = self.distPrimitivesSend( cmdStr )
5538 if "Invalid operation name" in output:
5539 main.log.warn( output )
5540 return main.ERROR
5541 elif "Done" in output:
5542 return main.TRUE
5543 except TypeError:
5544 main.log.exception( self.name + ": Object not as expected" )
5545 return main.ERROR
5546 except Exception:
5547 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005548 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005549
5550 def workQueueTakeAndComplete( self, queueName, number=1 ):
5551 """
5552 CLI command to take a value from the specified Work Queue and compelte it.
5553 This function uses the distributed primitives test app, which
5554 gives some cli access to distributed primitives for testing
5555 purposes only.
5556
5557 Required arguments:
5558 queueName - The name of the queue to add to
5559 number - The number of items to take and complete
5560 returns:
5561 main.TRUE on success, main.FALSE on failure and
5562 main.ERROR on error.
5563 """
5564 try:
5565 queueName = str( queueName )
5566 number = str( int( number ) )
5567 prefix = "work-queue-test"
5568 operation = "takeAndComplete"
5569 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5570 output = self.distPrimitivesSend( cmdStr )
5571 if "Invalid operation name" in output:
5572 main.log.warn( output )
5573 return main.ERROR
5574 elif "Done" in output:
5575 return main.TRUE
5576 except TypeError:
5577 main.log.exception( self.name + ": Object not as expected" )
5578 return main.ERROR
5579 except Exception:
5580 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005581 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005582
5583 def workQueueDestroy( self, queueName ):
5584 """
5585 CLI command to destroy the specified Work Queue.
5586 This function uses the distributed primitives test app, which
5587 gives some cli access to distributed primitives for testing
5588 purposes only.
5589
5590 Required arguments:
5591 queueName - The name of the queue to add to
5592 returns:
5593 main.TRUE on success, main.FALSE on failure and
5594 main.ERROR on error.
5595 """
5596 try:
5597 queueName = str( queueName )
5598 prefix = "work-queue-test"
5599 operation = "destroy"
5600 cmdStr = " ".join( [ prefix, queueName, operation ] )
5601 output = self.distPrimitivesSend( cmdStr )
5602 if "Invalid operation name" in output:
5603 main.log.warn( output )
5604 return main.ERROR
5605 return main.TRUE
5606 except TypeError:
5607 main.log.exception( self.name + ": Object not as expected" )
5608 return main.ERROR
5609 except Exception:
5610 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005611 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005612
5613 def workQueueTotalPending( self, queueName ):
5614 """
5615 CLI command to get the Total Pending items of the specified Work Queue.
5616 This function uses the distributed primitives test app, which
5617 gives some cli access to distributed primitives for testing
5618 purposes only.
5619
5620 Required arguments:
5621 queueName - The name of the queue to add to
5622 returns:
5623 The number of Pending items in the specified work queue or
5624 None on error
5625 """
5626 try:
5627 queueName = str( queueName )
5628 prefix = "work-queue-test"
5629 operation = "totalPending"
5630 cmdStr = " ".join( [ prefix, queueName, operation ] )
5631 output = self.distPrimitivesSend( cmdStr )
5632 pattern = r'\d+'
5633 if "Invalid operation name" in output:
5634 main.log.warn( output )
5635 return None
5636 else:
5637 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005638 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005639 except ( AttributeError, TypeError ):
5640 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5641 return None
5642 except Exception:
5643 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005644 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005645
5646 def workQueueTotalCompleted( self, queueName ):
5647 """
5648 CLI command to get the Total Completed items of the specified Work Queue.
5649 This function uses the distributed primitives test app, which
5650 gives some cli access to distributed primitives for testing
5651 purposes only.
5652
5653 Required arguments:
5654 queueName - The name of the queue to add to
5655 returns:
5656 The number of complete items in the specified work queue or
5657 None on error
5658 """
5659 try:
5660 queueName = str( queueName )
5661 prefix = "work-queue-test"
5662 operation = "totalCompleted"
5663 cmdStr = " ".join( [ prefix, queueName, operation ] )
5664 output = self.distPrimitivesSend( cmdStr )
5665 pattern = r'\d+'
5666 if "Invalid operation name" in output:
5667 main.log.warn( output )
5668 return None
5669 else:
5670 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005671 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005672 except ( AttributeError, TypeError ):
5673 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5674 return None
5675 except Exception:
5676 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005677 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005678
5679 def workQueueTotalInProgress( self, queueName ):
5680 """
5681 CLI command to get the Total In Progress items of the specified Work Queue.
5682 This function uses the distributed primitives test app, which
5683 gives some cli access to distributed primitives for testing
5684 purposes only.
5685
5686 Required arguments:
5687 queueName - The name of the queue to add to
5688 returns:
5689 The number of In Progress items in the specified work queue or
5690 None on error
5691 """
5692 try:
5693 queueName = str( queueName )
5694 prefix = "work-queue-test"
5695 operation = "totalInProgress"
5696 cmdStr = " ".join( [ prefix, queueName, operation ] )
5697 output = self.distPrimitivesSend( cmdStr )
5698 pattern = r'\d+'
5699 if "Invalid operation name" in output:
5700 main.log.warn( output )
5701 return None
5702 else:
5703 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005704 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005705 except ( AttributeError, TypeError ):
5706 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5707 return None
5708 except Exception:
5709 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005710 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005711
5712 def events( self, args='-a' ):
5713 """
5714 Description: Returns events -a command output
5715 Optional:
5716 add other arguments
5717 """
5718 try:
5719 cmdStr = "events"
5720 if args:
5721 cmdStr += " " + args
5722 handle = self.sendline( cmdStr )
5723 assert handle is not None, "Error in sendline"
5724 assert "Command not found:" not in handle, handle
5725 return handle
5726 except AssertionError:
5727 main.log.exception( "" )
5728 return None
5729 except TypeError:
5730 main.log.exception( self.name + ": Object not as expected" )
5731 return None
5732 except pexpect.EOF:
5733 main.log.error( self.name + ": EOF exception found" )
5734 main.log.error( self.name + ": " + self.handle.before )
5735 main.cleanAndExit()
5736 except Exception:
5737 main.log.exception( self.name + ": Uncaught exception!" )
5738 main.cleanAndExit()
5739
5740 def getMaster( self, deviceID ):
5741 """
5742 Description: Obtains current master using "roles" command for a specific deviceID
5743 """
5744 try:
5745 return str( self.getRole( deviceID )[ 'master' ] )
5746 except AssertionError:
5747 main.log.exception( "" )
5748 return None
5749 except TypeError:
5750 main.log.exception( self.name + ": Object not as expected" )
5751 return None
5752 except pexpect.EOF:
5753 main.log.error( self.name + ": EOF exception found" )
5754 main.log.error( self.name + ": " + self.handle.before )
5755 main.cleanAndExit()
5756 except Exception:
5757 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07005758 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08005759
5760 def issu( self ):
5761 """
5762 Short summary of In-Service Software Upgrade status
5763
5764 Returns the output of the cli command or None on Error
5765 """
5766 try:
5767 cmdStr = "issu"
5768 handle = self.sendline( cmdStr )
5769 assert handle is not None, "Error in sendline"
5770 assert "Command not found:" not in handle, handle
5771 assert "Unsupported command:" not in handle, handle
5772 return handle
5773 except AssertionError:
5774 main.log.exception( "" )
5775 return None
5776 except TypeError:
5777 main.log.exception( self.name + ": Object not as expected" )
5778 return None
5779 except pexpect.EOF:
5780 main.log.error( self.name + ": EOF exception found" )
5781 main.log.error( self.name + ": " + self.handle.before )
5782 main.cleanAndExit()
5783 except Exception:
5784 main.log.exception( self.name + ": Uncaught exception!" )
5785 main.cleanAndExit()
5786
5787 def issuInit( self ):
5788 """
5789 Initiates an In-Service Software Upgrade
5790
5791 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5792 """
5793 try:
5794 cmdStr = "issu init"
5795 handle = self.sendline( cmdStr )
5796 assert handle is not None, "Error in sendline"
5797 assert "Command not found:" not in handle, handle
5798 assert "Unsupported command:" not in handle, handle
5799 if "Initialized" in handle:
5800 return main.TRUE
5801 else:
5802 return main.FALSE
5803 except AssertionError:
5804 main.log.exception( "" )
5805 return main.ERROR
5806 except TypeError:
5807 main.log.exception( self.name + ": Object not as expected" )
5808 return main.ERROR
5809 except pexpect.EOF:
5810 main.log.error( self.name + ": EOF exception found" )
5811 main.log.error( self.name + ": " + self.handle.before )
5812 main.cleanAndExit()
5813 except Exception:
5814 main.log.exception( self.name + ": Uncaught exception!" )
5815 main.cleanAndExit()
5816
5817 def issuUpgrade( self ):
5818 """
5819 Transitions stores to upgraded nodes
5820
5821 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5822 """
5823 try:
5824 cmdStr = "issu upgrade"
5825 handle = self.sendline( cmdStr )
5826 assert handle is not None, "Error in sendline"
5827 assert "Command not found:" not in handle, handle
5828 assert "Unsupported command:" not in handle, handle
5829 if "Upgraded" in handle:
5830 return main.TRUE
5831 else:
5832 return main.FALSE
5833 except AssertionError:
5834 main.log.exception( "" )
5835 return main.ERROR
5836 except TypeError:
5837 main.log.exception( self.name + ": Object not as expected" )
5838 return main.ERROR
5839 except pexpect.EOF:
5840 main.log.error( self.name + ": EOF exception found" )
5841 main.log.error( self.name + ": " + self.handle.before )
5842 main.cleanAndExit()
5843 except Exception:
5844 main.log.exception( self.name + ": Uncaught exception!" )
5845 main.cleanAndExit()
5846
5847 def issuCommit( self ):
5848 """
5849 Finalizes an In-Service Software Upgrade
5850
5851 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5852 """
5853 try:
5854 cmdStr = "issu commit"
5855 handle = self.sendline( cmdStr )
5856 assert handle is not None, "Error in sendline"
5857 assert "Command not found:" not in handle, handle
5858 assert "Unsupported command:" not in handle, handle
5859 # TODO: Check the version returned by this command
5860 if "Committed version" in handle:
5861 return main.TRUE
5862 else:
5863 return main.FALSE
5864 except AssertionError:
5865 main.log.exception( "" )
5866 return main.ERROR
5867 except TypeError:
5868 main.log.exception( self.name + ": Object not as expected" )
5869 return main.ERROR
5870 except pexpect.EOF:
5871 main.log.error( self.name + ": EOF exception found" )
5872 main.log.error( self.name + ": " + self.handle.before )
5873 main.cleanAndExit()
5874 except Exception:
5875 main.log.exception( self.name + ": Uncaught exception!" )
5876 main.cleanAndExit()
5877
5878 def issuRollback( self ):
5879 """
5880 Rolls back an In-Service Software Upgrade
5881
5882 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5883 """
5884 try:
5885 cmdStr = "issu rollback"
5886 handle = self.sendline( cmdStr )
5887 assert handle is not None, "Error in sendline"
5888 assert "Command not found:" not in handle, handle
5889 assert "Unsupported command:" not in handle, handle
5890 # TODO: Check the version returned by this command
5891 if "Rolled back to version" in handle:
5892 return main.TRUE
5893 else:
5894 return main.FALSE
5895 except AssertionError:
5896 main.log.exception( "" )
5897 return main.ERROR
5898 except TypeError:
5899 main.log.exception( self.name + ": Object not as expected" )
5900 return main.ERROR
5901 except pexpect.EOF:
5902 main.log.error( self.name + ": EOF exception found" )
5903 main.log.error( self.name + ": " + self.handle.before )
5904 main.cleanAndExit()
5905 except Exception:
5906 main.log.exception( self.name + ": Uncaught exception!" )
5907 main.cleanAndExit()
5908
5909 def issuReset( self ):
5910 """
5911 Resets the In-Service Software Upgrade status after a rollback
5912
5913 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5914 """
5915 try:
5916 cmdStr = "issu reset"
5917 handle = self.sendline( cmdStr )
5918 assert handle is not None, "Error in sendline"
5919 assert "Command not found:" not in handle, handle
5920 assert "Unsupported command:" not in handle, handle
5921 # TODO: Check the version returned by this command
5922 if "Reset version" in handle:
5923 return main.TRUE
5924 else:
5925 return main.FALSE
5926 except AssertionError:
5927 main.log.exception( "" )
5928 return main.ERROR
5929 except TypeError:
5930 main.log.exception( self.name + ": Object not as expected" )
5931 return main.ERROR
5932 except pexpect.EOF:
5933 main.log.error( self.name + ": EOF exception found" )
5934 main.log.error( self.name + ": " + self.handle.before )
5935 main.cleanAndExit()
5936 except Exception:
5937 main.log.exception( self.name + ": Uncaught exception!" )
5938 main.cleanAndExit()
5939
5940 def issuStatus( self ):
5941 """
5942 Status of an In-Service Software Upgrade
5943
5944 Returns the output of the cli command or None on Error
5945 """
5946 try:
5947 cmdStr = "issu status"
5948 handle = self.sendline( cmdStr )
5949 assert handle is not None, "Error in sendline"
5950 assert "Command not found:" not in handle, handle
5951 assert "Unsupported command:" not in handle, handle
5952 return handle
5953 except AssertionError:
5954 main.log.exception( "" )
5955 return None
5956 except TypeError:
5957 main.log.exception( self.name + ": Object not as expected" )
5958 return None
5959 except pexpect.EOF:
5960 main.log.error( self.name + ": EOF exception found" )
5961 main.log.error( self.name + ": " + self.handle.before )
5962 main.cleanAndExit()
5963 except Exception:
5964 main.log.exception( self.name + ": Uncaught exception!" )
5965 main.cleanAndExit()
5966
5967 def issuVersion( self ):
5968 """
5969 Get the version of an In-Service Software Upgrade
5970
5971 Returns the output of the cli command or None on Error
5972 """
5973 try:
5974 cmdStr = "issu version"
5975 handle = self.sendline( cmdStr )
5976 assert handle is not None, "Error in sendline"
5977 assert "Command not found:" not in handle, handle
5978 assert "Unsupported command:" not in handle, handle
5979 return handle
5980 except AssertionError:
5981 main.log.exception( "" )
5982 return None
5983 except TypeError:
5984 main.log.exception( self.name + ": Object not as expected" )
5985 return None
5986 except pexpect.EOF:
5987 main.log.error( self.name + ": EOF exception found" )
5988 main.log.error( self.name + ": " + self.handle.before )
5989 main.cleanAndExit()
5990 except Exception:
5991 main.log.exception( self.name + ": Uncaught exception!" )
5992 main.cleanAndExit()