blob: ba63b82ec2d4951e5def5b34cc186aa611bbfb0f [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
5Copyright 2014 Open Networking Foundation (ONF)
6
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
14 (at your option) any later version.
15
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"""
24
25"""
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
Devin Limdc78e202017-06-09 18:30:07 -070064 def checkOptions(self, var, defaultVar):
65 if var is None or var == "":
66 return defaultVar
67 return var
kelvin8ec71442015-01-15 16:57:00 -080068 def connect( self, **connectargs ):
69 """
andrewonlab95ce8322014-10-13 14:12:04 -040070 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080071 """
andrewonlab95ce8322014-10-13 14:12:04 -040072 try:
73 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080074 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070075 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040076 for key in self.options:
77 if key == "home":
Devin Limdc78e202017-06-09 18:30:07 -070078 self.home = self.options[ key ]
79 elif key == "karaf_username":
80 self.karafUser = self.options[ key ]
81 elif key == "karaf_password":
82 self.karafPass = self.options[ key ]
83
84 self.home = self.checkOptions(self.home, "~/onos")
85 self.karafUser = self.checkOptions(self.karafUser, self.user_name)
86 self.karafPass = self.checkOptions(self.karafPass, self.pwd )
andrewonlab95ce8322014-10-13 14:12:04 -040087
kelvin-onlaba4074292015-07-09 15:19:49 -070088 for key in self.options:
89 if key == 'onosIp':
90 self.onosIp = self.options[ 'onosIp' ]
91 break
92
kelvin8ec71442015-01-15 16:57:00 -080093 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070094
95 try:
Jon Hallc6793552016-01-19 14:18:37 -080096 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070097 self.ip_address = os.getenv( str( self.ip_address ) )
98 else:
99 main.log.info( self.name +
100 ": Trying to connect to " +
101 self.ip_address )
102
103 except KeyError:
104 main.log.info( "Invalid host name," +
105 " connecting to local host instead" )
106 self.ip_address = 'localhost'
107 except Exception as inst:
108 main.log.error( "Uncaught exception: " + str( inst ) )
109
kelvin8ec71442015-01-15 16:57:00 -0800110 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800111 user_name=self.user_name,
112 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800113 port=self.port,
114 pwd=self.pwd,
115 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400116
kelvin8ec71442015-01-15 16:57:00 -0800117 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700118 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400119 if self.handle:
120 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800121 else:
122 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400123 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800124 except TypeError:
125 main.log.exception( self.name + ": Object not as expected" )
126 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400127 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800128 main.log.error( self.name + ": EOF exception found" )
129 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700130 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800131 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800132 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700133 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400134
kelvin8ec71442015-01-15 16:57:00 -0800135 def disconnect( self ):
136 """
andrewonlab95ce8322014-10-13 14:12:04 -0400137 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800138 """
Jon Halld61331b2015-02-17 16:35:47 -0800139 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400140 try:
Jon Hall61282e32015-03-19 11:34:11 -0700141 if self.handle:
142 i = self.logout()
143 if i == main.TRUE:
144 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700145 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700146 self.handle.sendline( "exit" )
147 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800148 except TypeError:
149 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800150 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400151 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800152 main.log.error( self.name + ": EOF exception found" )
153 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700154 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700155 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700156 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800157 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800158 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400159 response = main.FALSE
160 return response
161
kelvin8ec71442015-01-15 16:57:00 -0800162 def logout( self ):
163 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500164 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700165 Returns main.TRUE if exited CLI and
166 main.FALSE on timeout (not guranteed you are disconnected)
167 None on TypeError
168 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800169 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500170 try:
Jon Hall61282e32015-03-19 11:34:11 -0700171 if self.handle:
172 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700173 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ],
Jon Hall61282e32015-03-19 11:34:11 -0700174 timeout=10 )
175 if i == 0: # In ONOS CLI
176 self.handle.sendline( "logout" )
Devin Limdc78e202017-06-09 18:30:07 -0700177 j = self.handle.expect( [ self.prompt,
Jon Hallbfe00002016-04-05 10:23:54 -0700178 "Command not found:",
179 pexpect.TIMEOUT ] )
180 if j == 0: # Successfully logged out
181 return main.TRUE
182 elif j == 1 or j == 2:
183 # ONOS didn't fully load, and logout command isn't working
184 # or the command timed out
185 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700186 try:
Devin Limdc78e202017-06-09 18:30:07 -0700187 self.handle.expect( self.prompt )
Jon Hall64ab3bd2016-05-13 11:29:44 -0700188 except pexpect.TIMEOUT:
189 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700190 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700191 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700192 main.log.warn( "Unknown repsonse to logout command: '{}'",
193 repr( self.handle.before ) )
194 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700195 elif i == 1: # not in CLI
196 return main.TRUE
197 elif i == 3: # Timeout
198 return main.FALSE
199 else:
andrewonlab9627f432014-11-14 12:45:10 -0500200 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800201 except TypeError:
202 main.log.exception( self.name + ": Object not as expected" )
203 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500204 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800205 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700206 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700207 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700208 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700209 main.log.error( self.name +
210 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800211 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800212 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700213 main.cleanAndExit()
andrewonlab38d2b4a2014-11-13 16:28:47 -0500214
kelvin-onlabd3b64892015-01-20 13:26:24 -0800215 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800216 """
andrewonlab95ce8322014-10-13 14:12:04 -0400217 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800218
andrewonlab95ce8322014-10-13 14:12:04 -0400219 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800220 """
andrewonlab95ce8322014-10-13 14:12:04 -0400221 try:
222 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800223 main.log.error( "Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700224 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400225 else:
kelvin8ec71442015-01-15 16:57:00 -0800226 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800227 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800228 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400229 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800230 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800231 handleBefore = self.handle.before
232 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800233 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800234 self.handle.sendline("")
Devin Limdc78e202017-06-09 18:30:07 -0700235 self.handle.expect(self.prompt)
andrew@onlab.usc400b112015-01-21 15:33:19 -0800236 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400237
kelvin-onlabd3b64892015-01-20 13:26:24 -0800238 main.log.info( "Cell call returned: " + handleBefore +
239 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400240
241 return main.TRUE
242
Jon Halld4d4b372015-01-28 16:02:41 -0800243 except TypeError:
244 main.log.exception( self.name + ": Object not as expected" )
245 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400246 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800247 main.log.error( self.name + ": eof exception found" )
248 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700249 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800250 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800251 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700252 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -0800253
pingping-lin57a56ce2015-05-20 16:43:48 -0700254 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800255 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800256 """
Jon Hallefbd9792015-03-05 16:11:36 -0800257 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800258 by user would be used to set the current karaf shell idle timeout.
259 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800260 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800261 Below is an example to start a session with 60 seconds idle timeout
262 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800263
Hari Krishna25d42f72015-01-05 15:08:28 -0800264 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800265 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800266
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 Note: karafTimeout is left as str so that this could be read
268 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800269 """
You Wangf69ab392016-01-26 16:34:38 -0800270 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400271 try:
Jon Hall67253832016-12-05 09:47:13 -0800272 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800273 self.handle.sendline( "" )
274 x = self.handle.expect( [
Devin Limdc78e202017-06-09 18:30:07 -0700275 self.prompt, "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500276 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800277 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500278 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400279
Jon Hall67253832016-12-05 09:47:13 -0800280 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800281 if waitForStart:
282 # Wait for onos start ( -w ) and enter onos cli
283 startCliCommand = "onos -w "
284 else:
285 startCliCommand = "onos "
286 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800287 i = self.handle.expect( [
288 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700289 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400290
291 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800292 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800293 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800294 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800295 "config:property-set -p org.apache.karaf.shell\
296 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800297 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700298 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800299 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800300 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400301 return main.TRUE
302 else:
kelvin8ec71442015-01-15 16:57:00 -0800303 # If failed, send ctrl+c to process and try again
304 main.log.info( "Starting CLI failed. Retrying..." )
305 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800306 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800307 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
308 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400309 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800310 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800311 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800312 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800313 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800314 "config:property-set -p org.apache.karaf.shell\
315 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800316 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700317 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800318 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800319 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400320 return main.TRUE
321 else:
kelvin8ec71442015-01-15 16:57:00 -0800322 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800323 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400324 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400325
Jon Halld4d4b372015-01-28 16:02:41 -0800326 except TypeError:
327 main.log.exception( self.name + ": Object not as expected" )
328 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400329 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800330 main.log.error( self.name + ": EOF exception found" )
331 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700332 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800333 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800334 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700335 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400336
suibin zhang116647a2016-05-06 16:30:09 -0700337 def startCellCli( self, karafTimeout="",
338 commandlineTimeout=10, onosStartTimeout=60 ):
339 """
340 Start CLI on onos ecll handle.
341
342 karafTimeout is an optional argument. karafTimeout value passed
343 by user would be used to set the current karaf shell idle timeout.
344 Note that when ever this property is modified the shell will exit and
345 the subsequent login would reflect new idle timeout.
346 Below is an example to start a session with 60 seconds idle timeout
347 ( input value is in milliseconds ):
348
349 tValue = "60000"
350
351 Note: karafTimeout is left as str so that this could be read
352 and passed to startOnosCli from PARAMS file as str.
353 """
354
355 try:
356 self.handle.sendline( "" )
357 x = self.handle.expect( [
Devin Limdc78e202017-06-09 18:30:07 -0700358 self.prompt, "onos>" ], commandlineTimeout)
suibin zhang116647a2016-05-06 16:30:09 -0700359
360 if x == 1:
361 main.log.info( "ONOS cli is already running" )
362 return main.TRUE
363
364 # Wait for onos start ( -w ) and enter onos cli
365 self.handle.sendline( "/opt/onos/bin/onos" )
366 i = self.handle.expect( [
367 "onos>",
368 pexpect.TIMEOUT ], onosStartTimeout )
369
370 if i == 0:
371 main.log.info( self.name + " CLI Started successfully" )
372 if karafTimeout:
373 self.handle.sendline(
374 "config:property-set -p org.apache.karaf.shell\
375 sshIdleTimeout " +
376 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700377 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700378 self.handle.sendline( "/opt/onos/bin/onos" )
379 self.handle.expect( "onos>" )
380 return main.TRUE
381 else:
382 # If failed, send ctrl+c to process and try again
383 main.log.info( "Starting CLI failed. Retrying..." )
384 self.handle.send( "\x03" )
385 self.handle.sendline( "/opt/onos/bin/onos" )
386 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
387 timeout=30 )
388 if i == 0:
389 main.log.info( self.name + " CLI Started " +
390 "successfully after retry attempt" )
391 if karafTimeout:
392 self.handle.sendline(
393 "config:property-set -p org.apache.karaf.shell\
394 sshIdleTimeout " +
395 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700396 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700397 self.handle.sendline( "/opt/onos/bin/onos" )
398 self.handle.expect( "onos>" )
399 return main.TRUE
400 else:
401 main.log.error( "Connection to CLI " +
402 self.name + " timeout" )
403 return main.FALSE
404
405 except TypeError:
406 main.log.exception( self.name + ": Object not as expected" )
407 return None
408 except pexpect.EOF:
409 main.log.error( self.name + ": EOF exception found" )
410 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700411 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700412 except Exception:
413 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700414 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700415
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800416 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800417 """
418 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800419 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800420 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700421 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800422 Available level: DEBUG, TRACE, INFO, WARN, ERROR
423 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800424 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800425 """
426 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800427 lvlStr = ""
428 if level:
429 lvlStr = "--level=" + level
430
kelvin-onlab338f5512015-02-06 10:53:16 -0800431 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700432 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800433 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800434
kelvin-onlab9f541032015-02-04 16:19:53 -0800435 response = self.handle.before
436 if re.search( "Error", response ):
437 return main.FALSE
438 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700439 except pexpect.TIMEOUT:
440 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700441 if noExit:
442 main.cleanup()
443 return None
444 else:
Devin Lim44075962017-08-11 10:56:37 -0700445 main.cleanAndExit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800446 except pexpect.EOF:
447 main.log.error( self.name + ": EOF exception found" )
448 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700449 if noExit:
450 main.cleanup()
451 return None
452 else:
Devin Lim44075962017-08-11 10:56:37 -0700453 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800454 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800455 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700456 if noExit:
457 main.cleanup()
458 return None
459 else:
Devin Lim44075962017-08-11 10:56:37 -0700460 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400461
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700462 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, dollarSign=False ):
kelvin8ec71442015-01-15 16:57:00 -0800463 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800464 Send a completely user specified string to
465 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400466 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800467
YPZhang14a4aa92016-07-15 13:37:15 -0700468 if noExit is True, TestON will not exit, and return None
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700469 if dollarSign is True, TestON will not expect for '$' as a new CLI or onos> prompt
470 since '$' can be in the output.
YPZhangebf9eb52016-05-12 15:20:24 -0700471
andrewonlaba18f6bf2014-10-13 19:31:54 -0400472 Warning: There are no sanity checking to commands
473 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800474
kelvin8ec71442015-01-15 16:57:00 -0800475 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400476 try:
Jon Halla495f562016-05-16 18:03:26 -0700477 # Try to reconnect if disconnected from cli
478 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700479 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ] )
Jon Halla495f562016-05-16 18:03:26 -0700480 if i == 1:
481 main.log.error( self.name + ": onos cli session closed. ")
482 if self.onosIp:
483 main.log.warn( "Trying to reconnect " + self.onosIp )
484 reconnectResult = self.startOnosCli( self.onosIp )
485 if reconnectResult:
486 main.log.info( self.name + ": onos cli session reconnected." )
487 else:
488 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700489 if noExit:
490 return None
491 else:
Devin Lim44075962017-08-11 10:56:37 -0700492 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700493 else:
Devin Lim44075962017-08-11 10:56:37 -0700494 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700495 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700496 main.log.warn( "Timeout when testing cli responsiveness" )
497 main.log.debug( self.handle.before )
498 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700499 self.handle.expect( "onos>" )
500
Jon Hall14a03b52016-05-11 12:07:30 -0700501 if debug:
502 # NOTE: This adds and average of .4 seconds per call
503 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700504 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800505 self.handle.sendline( cmdStr )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700506 if dollarSign:
507 i = self.handle.expect( ["onos>"], timeout )
508 else:
Devin Limdc78e202017-06-09 18:30:07 -0700509 i = self.handle.expect( ["onos>", self.prompt], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800510 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800511 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800512 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
513 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700514 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700515 main.log.debug( self.name + ": Raw output" )
516 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700517
518 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800519 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800520 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700521 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700522 main.log.debug( self.name + ": ansiEscape output" )
523 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700524
kelvin-onlabfb521662015-02-27 09:52:40 -0800525 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800526 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700527 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700528 main.log.debug( self.name + ": Removed extra returns " +
529 "from output" )
530 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700531
532 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800533 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700534 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700535 main.log.debug( self.name + ": parsed and stripped output" )
536 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700537
Jon Hall63604932015-02-26 17:09:50 -0800538 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700539 output = response.split( cmdStr.strip(), 1 )
540 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700541 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700542 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700543 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800544 output = output[1].strip()
545 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800546 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800547 return output
GlennRCed771242016-01-13 17:02:47 -0800548 except pexpect.TIMEOUT:
549 main.log.error( self.name + ":ONOS timeout" )
550 if debug:
551 main.log.debug( self.handle.before )
552 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700553 except IndexError:
554 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700555 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700556 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800557 except TypeError:
558 main.log.exception( self.name + ": Object not as expected" )
559 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400560 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800561 main.log.error( self.name + ": EOF exception found" )
562 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700563 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700564 return None
565 else:
Devin Lim44075962017-08-11 10:56:37 -0700566 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800567 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800568 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700569 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700570 return None
571 else:
Devin Lim44075962017-08-11 10:56:37 -0700572 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400573
kelvin8ec71442015-01-15 16:57:00 -0800574 # IMPORTANT NOTE:
575 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800576 # the cli command changing 'a:b' with 'aB'.
577 # Ex ) onos:topology > onosTopology
578 # onos:links > onosLinks
579 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800580
kelvin-onlabd3b64892015-01-20 13:26:24 -0800581 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800582 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400583 Adds a new cluster node by ID and address information.
584 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800585 * nodeId
586 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400587 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800588 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800589 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400590 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800591 cmdStr = "add-node " + str( nodeId ) + " " +\
592 str( ONOSIp ) + " " + str( tcpPort )
593 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700594 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800595 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800596 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800597 main.log.error( "Error in adding node" )
598 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800599 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400600 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800601 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400602 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800603 except AssertionError:
604 main.log.exception( "" )
605 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800606 except TypeError:
607 main.log.exception( self.name + ": Object not as expected" )
608 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400609 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800610 main.log.error( self.name + ": EOF exception found" )
611 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700612 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800613 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800614 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700615 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400616
kelvin-onlabd3b64892015-01-20 13:26:24 -0800617 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800618 """
andrewonlab86dc3082014-10-13 18:18:38 -0400619 Removes a cluster by ID
620 Issues command: 'remove-node [<node-id>]'
621 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800622 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800623 """
andrewonlab86dc3082014-10-13 18:18:38 -0400624 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400625
kelvin-onlabd3b64892015-01-20 13:26:24 -0800626 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700627 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700628 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800629 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700630 if re.search( "Error", handle ):
631 main.log.error( "Error in removing node" )
632 main.log.error( handle )
633 return main.FALSE
634 else:
635 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800636 except AssertionError:
637 main.log.exception( "" )
638 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800639 except TypeError:
640 main.log.exception( self.name + ": Object not as expected" )
641 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400642 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800643 main.log.error( self.name + ": EOF exception found" )
644 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700645 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800646 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800647 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700648 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400649
Jon Hall61282e32015-03-19 11:34:11 -0700650 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800651 """
andrewonlab7c211572014-10-15 16:45:20 -0400652 List the nodes currently visible
653 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700654 Optional argument:
655 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800656 """
andrewonlab7c211572014-10-15 16:45:20 -0400657 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700658 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700659 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700660 cmdStr += " -j"
661 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700662 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800663 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700664 return output
Jon Hallc6793552016-01-19 14:18:37 -0800665 except AssertionError:
666 main.log.exception( "" )
667 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800668 except TypeError:
669 main.log.exception( self.name + ": Object not as expected" )
670 return None
andrewonlab7c211572014-10-15 16:45:20 -0400671 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800672 main.log.error( self.name + ": EOF exception found" )
673 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700674 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800675 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800676 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700677 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400678
kelvin8ec71442015-01-15 16:57:00 -0800679 def topology( self ):
680 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700681 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700682 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700683 Return:
684 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800685 """
andrewonlab95ce8322014-10-13 14:12:04 -0400686 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700687 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800688 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800689 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800690 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700691 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400692 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800693 except AssertionError:
694 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800695 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800696 except TypeError:
697 main.log.exception( self.name + ": Object not as expected" )
698 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400699 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800700 main.log.error( self.name + ": EOF exception found" )
701 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700702 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800703 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800704 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700705 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800706
jenkins7ead5a82015-03-13 10:28:21 -0700707 def deviceRemove( self, deviceId ):
708 """
709 Removes particular device from storage
710
711 TODO: refactor this function
712 """
713 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700714 cmdStr = "device-remove " + str( deviceId )
715 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800716 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800717 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700718 if re.search( "Error", handle ):
719 main.log.error( "Error in removing device" )
720 main.log.error( handle )
721 return main.FALSE
722 else:
723 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800724 except AssertionError:
725 main.log.exception( "" )
726 return None
jenkins7ead5a82015-03-13 10:28:21 -0700727 except TypeError:
728 main.log.exception( self.name + ": Object not as expected" )
729 return None
730 except pexpect.EOF:
731 main.log.error( self.name + ": EOF exception found" )
732 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700733 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700734 except Exception:
735 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700736 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700737
kelvin-onlabd3b64892015-01-20 13:26:24 -0800738 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800739 """
Jon Hall7b02d952014-10-17 20:14:54 -0400740 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400741 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800742 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800743 """
andrewonlab86dc3082014-10-13 18:18:38 -0400744 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700745 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800746 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700747 cmdStr += " -j"
748 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800749 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800750 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700751 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800752 except AssertionError:
753 main.log.exception( "" )
754 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800755 except TypeError:
756 main.log.exception( self.name + ": Object not as expected" )
757 return None
andrewonlab7c211572014-10-15 16:45:20 -0400758 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800759 main.log.error( self.name + ": EOF exception found" )
760 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700761 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800762 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800763 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700764 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400765
kelvin-onlabd3b64892015-01-20 13:26:24 -0800766 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800767 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800768 This balances the devices across all controllers
769 by issuing command: 'onos> onos:balance-masters'
770 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800771 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800772 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700774 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800775 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800776 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700777 if re.search( "Error", handle ):
778 main.log.error( "Error in balancing masters" )
779 main.log.error( handle )
780 return main.FALSE
781 else:
782 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800783 except AssertionError:
784 main.log.exception( "" )
785 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800786 except TypeError:
787 main.log.exception( self.name + ": Object not as expected" )
788 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800789 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800790 main.log.error( self.name + ": EOF exception found" )
791 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700792 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800793 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800794 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700795 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800796
Jon Hallc6793552016-01-19 14:18:37 -0800797 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700798 """
799 Returns the output of the masters command.
800 Optional argument:
801 * jsonFormat - boolean indicating if you want output in json
802 """
803 try:
804 cmdStr = "onos:masters"
805 if jsonFormat:
806 cmdStr += " -j"
807 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700808 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800809 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700810 return output
Jon Hallc6793552016-01-19 14:18:37 -0800811 except AssertionError:
812 main.log.exception( "" )
813 return None
acsmars24950022015-07-30 18:00:43 -0700814 except TypeError:
815 main.log.exception( self.name + ": Object not as expected" )
816 return None
817 except pexpect.EOF:
818 main.log.error( self.name + ": EOF exception found" )
819 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700820 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700821 except Exception:
822 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700823 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700824
Jon Hallc6793552016-01-19 14:18:37 -0800825 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700826 """
827 Uses the master command to check that the devices' leadership
828 is evenly divided
829
830 Dependencies: checkMasters() and summary()
831
Jon Hall6509dbf2016-06-21 17:01:17 -0700832 Returns main.TRUE if the devices are balanced
833 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700834 Exits on Exception
835 Returns None on TypeError
836 """
837 try:
Jon Hallc6793552016-01-19 14:18:37 -0800838 summaryOutput = self.summary()
839 totalDevices = json.loads( summaryOutput )[ "devices" ]
840 except ( TypeError, ValueError ):
841 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
842 return None
843 try:
acsmars24950022015-07-30 18:00:43 -0700844 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800845 mastersOutput = self.checkMasters()
846 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700847 first = masters[ 0 ][ "size" ]
848 for master in masters:
849 totalOwnedDevices += master[ "size" ]
850 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
851 main.log.error( "Mastership not balanced" )
852 main.log.info( "\n" + self.checkMasters( False ) )
853 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700854 main.log.info( "Mastership balanced between " +
855 str( len(masters) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700856 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800857 except ( TypeError, ValueError ):
858 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700859 return None
860 except pexpect.EOF:
861 main.log.error( self.name + ": EOF exception found" )
862 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700863 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700864 except Exception:
865 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700866 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700867
YPZhangfebf7302016-05-24 16:45:56 -0700868 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800869 """
Jon Halle8217482014-10-17 13:49:14 -0400870 Lists all core links
871 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800872 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800873 """
Jon Halle8217482014-10-17 13:49:14 -0400874 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700875 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800876 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700877 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700878 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800879 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800880 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700881 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800882 except AssertionError:
883 main.log.exception( "" )
884 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800885 except TypeError:
886 main.log.exception( self.name + ": Object not as expected" )
887 return None
Jon Halle8217482014-10-17 13:49:14 -0400888 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800889 main.log.error( self.name + ": EOF exception found" )
890 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700891 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800892 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800893 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700894 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400895
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800897 """
Jon Halle8217482014-10-17 13:49:14 -0400898 Lists all ports
899 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800900 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800901 """
Jon Halle8217482014-10-17 13:49:14 -0400902 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700903 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800904 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700905 cmdStr += " -j"
906 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800907 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800908 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700909 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800910 except AssertionError:
911 main.log.exception( "" )
912 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800913 except TypeError:
914 main.log.exception( self.name + ": Object not as expected" )
915 return None
Jon Halle8217482014-10-17 13:49:14 -0400916 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800917 main.log.error( self.name + ": EOF exception found" )
918 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700919 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800920 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800921 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700922 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400923
kelvin-onlabd3b64892015-01-20 13:26:24 -0800924 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800925 """
Jon Hall983a1702014-10-28 18:44:22 -0400926 Lists all devices and the controllers with roles assigned to them
927 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800928 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800929 """
andrewonlab7c211572014-10-15 16:45:20 -0400930 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700931 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800932 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700933 cmdStr += " -j"
934 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800935 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800936 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700937 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800938 except AssertionError:
939 main.log.exception( "" )
940 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800941 except TypeError:
942 main.log.exception( self.name + ": Object not as expected" )
943 return None
Jon Hall983a1702014-10-28 18:44:22 -0400944 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800945 main.log.error( self.name + ": EOF exception found" )
946 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700947 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800948 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800949 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700950 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -0400951
kelvin-onlabd3b64892015-01-20 13:26:24 -0800952 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800953 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800954 Given the a string containing the json representation of the "roles"
955 cli command and a partial or whole device id, returns a json object
956 containing the roles output for the first device whose id contains
957 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400958
959 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800960 A dict of the role assignments for the given device or
961 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800962 """
Jon Hall983a1702014-10-28 18:44:22 -0400963 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800964 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400965 return None
966 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800967 rawRoles = self.roles()
968 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800969 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800970 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800971 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800972 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400973 return device
974 return None
Jon Hallc6793552016-01-19 14:18:37 -0800975 except ( TypeError, ValueError ):
976 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800977 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400978 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800979 main.log.error( self.name + ": EOF exception found" )
980 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700981 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800982 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800983 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700984 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -0800985
kelvin-onlabd3b64892015-01-20 13:26:24 -0800986 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800987 """
Jon Hall94fd0472014-12-08 11:52:42 -0800988 Iterates through each device and checks if there is a master assigned
989 Returns: main.TRUE if each device has a master
990 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800991 """
Jon Hall94fd0472014-12-08 11:52:42 -0800992 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800993 rawRoles = self.roles()
994 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800995 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800996 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800997 # print device
998 if device[ 'master' ] == "none":
999 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001000 return main.FALSE
1001 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001002 except ( TypeError, ValueError ):
1003 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001004 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001005 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001006 main.log.error( self.name + ": EOF exception found" )
1007 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001008 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001009 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001010 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001011 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001012
kelvin-onlabd3b64892015-01-20 13:26:24 -08001013 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001014 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001015 Returns string of paths, and the cost.
1016 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001017 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001018 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001019 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1020 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001021 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001022 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001023 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001024 main.log.error( "Error in getting paths" )
1025 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001026 else:
kelvin8ec71442015-01-15 16:57:00 -08001027 path = handle.split( ";" )[ 0 ]
1028 cost = handle.split( ";" )[ 1 ]
1029 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001030 except AssertionError:
1031 main.log.exception( "" )
1032 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001033 except TypeError:
1034 main.log.exception( self.name + ": Object not as expected" )
1035 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001036 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001037 main.log.error( self.name + ": EOF exception found" )
1038 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001039 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001040 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001041 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001042 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001043
kelvin-onlabd3b64892015-01-20 13:26:24 -08001044 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001045 """
Jon Hallffb386d2014-11-21 13:43:38 -08001046 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001047 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001048 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001049 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001050 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001051 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001052 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001053 cmdStr += " -j"
1054 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001055 if handle:
1056 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001057 # TODO: Maybe make this less hardcoded
1058 # ConsistentMap Exceptions
1059 assert "org.onosproject.store.service" not in handle
1060 # Node not leader
1061 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001062 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001063 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001064 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001065 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001066 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001067 except TypeError:
1068 main.log.exception( self.name + ": Object not as expected" )
1069 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001070 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001071 main.log.error( self.name + ": EOF exception found" )
1072 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001073 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001074 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001075 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001076 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001077
kelvin-onlabd3b64892015-01-20 13:26:24 -08001078 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001079 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001080 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001081
Jon Hallefbd9792015-03-05 16:11:36 -08001082 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001083 partial mac address
1084
Jon Hall42db6dc2014-10-24 19:03:48 -04001085 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001086 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001087 try:
kelvin8ec71442015-01-15 16:57:00 -08001088 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001089 return None
1090 else:
1091 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001092 rawHosts = self.hosts()
1093 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001094 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001095 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001096 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001097 if not host:
1098 pass
1099 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001100 return host
1101 return None
Jon Hallc6793552016-01-19 14:18:37 -08001102 except ( TypeError, ValueError ):
1103 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001104 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001105 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001106 main.log.error( self.name + ": EOF exception found" )
1107 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001108 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001109 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001110 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001111 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001112
kelvin-onlabd3b64892015-01-20 13:26:24 -08001113 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001114 """
1115 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001116 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001117
andrewonlab3f0a4af2014-10-17 12:25:14 -04001118 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001120 IMPORTANT:
1121 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001122 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001123 Furthermore, it assumes that value of VLAN is '-1'
1124 Description:
kelvin8ec71442015-01-15 16:57:00 -08001125 Converts mininet hosts ( h1, h2, h3... ) into
1126 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1127 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001128 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001130
kelvin-onlabd3b64892015-01-20 13:26:24 -08001131 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001132 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 hostHex = hex( int( host ) ).zfill( 12 )
1134 hostHex = str( hostHex ).replace( 'x', '0' )
1135 i = iter( str( hostHex ) )
1136 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1137 hostHex = hostHex + "/-1"
1138 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001139
kelvin-onlabd3b64892015-01-20 13:26:24 -08001140 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001141
Jon Halld4d4b372015-01-28 16:02:41 -08001142 except TypeError:
1143 main.log.exception( self.name + ": Object not as expected" )
1144 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001145 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001146 main.log.error( self.name + ": EOF exception found" )
1147 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001148 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001149 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001150 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001151 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001152
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001153 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001154 """
andrewonlabe6745342014-10-17 14:29:13 -04001155 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001156 * hostIdOne: ONOS host id for host1
1157 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001158 Optional:
1159 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001160 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001161 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001162 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001163 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001164 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001165 Returns:
1166 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001167 """
andrewonlabe6745342014-10-17 14:29:13 -04001168 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001169 cmdStr = "add-host-intent "
1170 if vlanId:
1171 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001172 if setVlan:
1173 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001174 if encap:
1175 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001176 if bandwidth:
1177 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001178 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001179 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001180 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001181 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001182 if re.search( "Error", handle ):
1183 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001184 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001185 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001186 else:
1187 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001188 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1189 match = re.search('id=0x([\da-f]+),', handle)
1190 if match:
1191 return match.group()[3:-1]
1192 else:
1193 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001194 main.log.debug( "Response from ONOS was: " +
1195 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001196 return None
Jon Hallc6793552016-01-19 14:18:37 -08001197 except AssertionError:
1198 main.log.exception( "" )
1199 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001200 except TypeError:
1201 main.log.exception( self.name + ": Object not as expected" )
1202 return None
andrewonlabe6745342014-10-17 14:29:13 -04001203 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001204 main.log.error( self.name + ": EOF exception found" )
1205 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001206 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001207 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001208 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001209 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001210
kelvin-onlabd3b64892015-01-20 13:26:24 -08001211 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001212 """
andrewonlab7b31d232014-10-24 13:31:47 -04001213 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001214 * ingressDevice: device id of ingress device
1215 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001216 Optional:
1217 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001218 Description:
1219 Adds an optical intent by specifying an ingress and egress device
1220 Returns:
1221 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001222 """
andrewonlab7b31d232014-10-24 13:31:47 -04001223 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001224 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1225 " " + str( egressDevice )
1226 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001227 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001228 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001229 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001230 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001231 main.log.error( "Error in adding Optical intent" )
1232 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001233 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001234 main.log.info( "Optical intent installed between " +
1235 str( ingressDevice ) + " and " +
1236 str( egressDevice ) )
1237 match = re.search('id=0x([\da-f]+),', handle)
1238 if match:
1239 return match.group()[3:-1]
1240 else:
1241 main.log.error( "Error, intent ID not found" )
1242 return None
Jon Hallc6793552016-01-19 14:18:37 -08001243 except AssertionError:
1244 main.log.exception( "" )
1245 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001246 except TypeError:
1247 main.log.exception( self.name + ": Object not as expected" )
1248 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001249 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001250 main.log.error( self.name + ": EOF exception found" )
1251 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001252 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001253 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001254 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001255 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001256
kelvin-onlabd3b64892015-01-20 13:26:24 -08001257 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001258 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 ingressDevice,
1260 egressDevice,
1261 portIngress="",
1262 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001263 ethType="",
1264 ethSrc="",
1265 ethDst="",
1266 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001267 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001268 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001269 ipProto="",
1270 ipSrc="",
1271 ipDst="",
1272 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001273 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001274 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001275 setVlan="",
1276 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001277 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001278 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 * ingressDevice: device id of ingress device
1280 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001281 Optional:
1282 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001283 * ethSrc: specify ethSrc ( i.e. src mac addr )
1284 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001285 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001286 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001287 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001288 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001289 * ipSrc: specify ip source address
1290 * ipDst: specify ip destination address
1291 * tcpSrc: specify tcp source port
1292 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001293 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001294 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001295 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001296 Description:
kelvin8ec71442015-01-15 16:57:00 -08001297 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001298 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001299 Returns:
1300 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001301
Jon Halle3f39ff2015-01-13 11:50:53 -08001302 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001303 options developers provide for point-to-point
1304 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001305 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001306 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001307 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001308
Jeremy Songsterff553672016-05-12 17:06:23 -07001309 if ethType:
1310 cmd += " --ethType " + str( ethType )
1311 if ethSrc:
1312 cmd += " --ethSrc " + str( ethSrc )
1313 if ethDst:
1314 cmd += " --ethDst " + str( ethDst )
1315 if bandwidth:
1316 cmd += " --bandwidth " + str( bandwidth )
1317 if lambdaAlloc:
1318 cmd += " --lambda "
1319 if ipProto:
1320 cmd += " --ipProto " + str( ipProto )
1321 if ipSrc:
1322 cmd += " --ipSrc " + str( ipSrc )
1323 if ipDst:
1324 cmd += " --ipDst " + str( ipDst )
1325 if tcpSrc:
1326 cmd += " --tcpSrc " + str( tcpSrc )
1327 if tcpDst:
1328 cmd += " --tcpDst " + str( tcpDst )
1329 if vlanId:
1330 cmd += " -v " + str( vlanId )
1331 if setVlan:
1332 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001333 if encap:
1334 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001335 if protected:
1336 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001337
kelvin8ec71442015-01-15 16:57:00 -08001338 # Check whether the user appended the port
1339 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001340 if "/" in ingressDevice:
1341 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001342 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001343 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001344 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001345 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001346 # Would it make sense to throw an exception and exit
1347 # the test?
1348 return None
andrewonlab36af3822014-11-18 17:48:18 -05001349
kelvin8ec71442015-01-15 16:57:00 -08001350 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001351 str( ingressDevice ) + "/" +\
1352 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001353
kelvin-onlabd3b64892015-01-20 13:26:24 -08001354 if "/" in egressDevice:
1355 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001356 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001357 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001358 main.log.error( "You must specify the egress port" )
1359 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001360
kelvin8ec71442015-01-15 16:57:00 -08001361 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001362 str( egressDevice ) + "/" +\
1363 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001364
kelvin-onlab898a6c62015-01-16 14:13:53 -08001365 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001366 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001367 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001368 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001369 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001370 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001371 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001372 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001373 # TODO: print out all the options in this message?
1374 main.log.info( "Point-to-point intent installed between " +
1375 str( ingressDevice ) + " and " +
1376 str( egressDevice ) )
1377 match = re.search('id=0x([\da-f]+),', handle)
1378 if match:
1379 return match.group()[3:-1]
1380 else:
1381 main.log.error( "Error, intent ID not found" )
1382 return None
Jon Hallc6793552016-01-19 14:18:37 -08001383 except AssertionError:
1384 main.log.exception( "" )
1385 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001386 except TypeError:
1387 main.log.exception( self.name + ": Object not as expected" )
1388 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001389 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001390 main.log.error( self.name + ": EOF exception found" )
1391 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001392 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001393 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001394 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001395 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001396
kelvin-onlabd3b64892015-01-20 13:26:24 -08001397 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001398 self,
shahshreyac2f97072015-03-19 17:04:29 -07001399 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001400 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001401 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001402 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001403 ethType="",
1404 ethSrc="",
1405 ethDst="",
1406 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001407 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001408 ipProto="",
1409 ipSrc="",
1410 ipDst="",
1411 tcpSrc="",
1412 tcpDst="",
1413 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001414 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001415 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001416 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001417 partial=False,
1418 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001419 """
shahshreyad0c80432014-12-04 16:56:05 -08001420 Note:
shahshreya70622b12015-03-19 17:19:00 -07001421 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001422 is same. That is, all ingress devices include port numbers
1423 with a "/" or all ingress devices could specify device
1424 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001425 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001426 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001427 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001428 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001429 Optional:
1430 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001431 * ethSrc: specify ethSrc ( i.e. src mac addr )
1432 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001433 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001434 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001435 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001436 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001437 * ipSrc: specify ip source address
1438 * ipDst: specify ip destination address
1439 * tcpSrc: specify tcp source port
1440 * tcpDst: specify tcp destination port
1441 * setEthSrc: action to Rewrite Source MAC Address
1442 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001443 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001444 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001445 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001446 Description:
kelvin8ec71442015-01-15 16:57:00 -08001447 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001448 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001449 Returns:
1450 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001451
Jon Halle3f39ff2015-01-13 11:50:53 -08001452 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001453 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001454 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001455 """
shahshreyad0c80432014-12-04 16:56:05 -08001456 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001457 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001458
Jeremy Songsterff553672016-05-12 17:06:23 -07001459 if ethType:
1460 cmd += " --ethType " + str( ethType )
1461 if ethSrc:
1462 cmd += " --ethSrc " + str( ethSrc )
1463 if ethDst:
1464 cmd += " --ethDst " + str( ethDst )
1465 if bandwidth:
1466 cmd += " --bandwidth " + str( bandwidth )
1467 if lambdaAlloc:
1468 cmd += " --lambda "
1469 if ipProto:
1470 cmd += " --ipProto " + str( ipProto )
1471 if ipSrc:
1472 cmd += " --ipSrc " + str( ipSrc )
1473 if ipDst:
1474 cmd += " --ipDst " + str( ipDst )
1475 if tcpSrc:
1476 cmd += " --tcpSrc " + str( tcpSrc )
1477 if tcpDst:
1478 cmd += " --tcpDst " + str( tcpDst )
1479 if setEthSrc:
1480 cmd += " --setEthSrc " + str( setEthSrc )
1481 if setEthDst:
1482 cmd += " --setEthDst " + str( setEthDst )
1483 if vlanId:
1484 cmd += " -v " + str( vlanId )
1485 if setVlan:
1486 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001487 if partial:
1488 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001489 if encap:
1490 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001491
kelvin8ec71442015-01-15 16:57:00 -08001492 # Check whether the user appended the port
1493 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001494
1495 if portIngressList is None:
1496 for ingressDevice in ingressDeviceList:
1497 if "/" in ingressDevice:
1498 cmd += " " + str( ingressDevice )
1499 else:
1500 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001501 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001502 # TODO: perhaps more meaningful return
1503 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001504 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001505 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001506 for ingressDevice, portIngress in zip( ingressDeviceList,
1507 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001508 cmd += " " + \
1509 str( ingressDevice ) + "/" +\
1510 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001511 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001512 main.log.error( "Device list and port list does not " +
1513 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001514 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001515 if "/" in egressDevice:
1516 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001517 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001518 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001519 main.log.error( "You must specify " +
1520 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001521 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001522
kelvin8ec71442015-01-15 16:57:00 -08001523 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001524 str( egressDevice ) + "/" +\
1525 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001526 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001527 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001528 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001529 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001530 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001531 main.log.error( "Error in adding multipoint-to-singlepoint " +
1532 "intent" )
1533 return None
shahshreyad0c80432014-12-04 16:56:05 -08001534 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001535 match = re.search('id=0x([\da-f]+),', handle)
1536 if match:
1537 return match.group()[3:-1]
1538 else:
1539 main.log.error( "Error, intent ID not found" )
1540 return None
Jon Hallc6793552016-01-19 14:18:37 -08001541 except AssertionError:
1542 main.log.exception( "" )
1543 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001544 except TypeError:
1545 main.log.exception( self.name + ": Object not as expected" )
1546 return None
1547 except pexpect.EOF:
1548 main.log.error( self.name + ": EOF exception found" )
1549 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001550 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001551 except Exception:
1552 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001553 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001554
1555 def addSinglepointToMultipointIntent(
1556 self,
1557 ingressDevice,
1558 egressDeviceList,
1559 portIngress="",
1560 portEgressList=None,
1561 ethType="",
1562 ethSrc="",
1563 ethDst="",
1564 bandwidth="",
1565 lambdaAlloc=False,
1566 ipProto="",
1567 ipSrc="",
1568 ipDst="",
1569 tcpSrc="",
1570 tcpDst="",
1571 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001572 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001573 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001574 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001575 partial=False,
1576 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001577 """
1578 Note:
1579 This function assumes the format of all egress devices
1580 is same. That is, all egress devices include port numbers
1581 with a "/" or all egress devices could specify device
1582 ids and port numbers seperately.
1583 Required:
1584 * EgressDeviceList: List of device ids of egress device
1585 ( Atleast 2 eress devices required in the list )
1586 * ingressDevice: device id of ingress device
1587 Optional:
1588 * ethType: specify ethType
1589 * ethSrc: specify ethSrc ( i.e. src mac addr )
1590 * ethDst: specify ethDst ( i.e. dst mac addr )
1591 * bandwidth: specify bandwidth capacity of link
1592 * lambdaAlloc: if True, intent will allocate lambda
1593 for the specified intent
1594 * ipProto: specify ip protocol
1595 * ipSrc: specify ip source address
1596 * ipDst: specify ip destination address
1597 * tcpSrc: specify tcp source port
1598 * tcpDst: specify tcp destination port
1599 * setEthSrc: action to Rewrite Source MAC Address
1600 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001601 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001602 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001603 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001604 Description:
1605 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1606 specifying device id's and optional fields
1607 Returns:
1608 A string of the intent id or None on error
1609
1610 NOTE: This function may change depending on the
1611 options developers provide for singlepoint-to-multipoint
1612 intent via cli
1613 """
1614 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001615 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001616
Jeremy Songsterff553672016-05-12 17:06:23 -07001617 if ethType:
1618 cmd += " --ethType " + str( ethType )
1619 if ethSrc:
1620 cmd += " --ethSrc " + str( ethSrc )
1621 if ethDst:
1622 cmd += " --ethDst " + str( ethDst )
1623 if bandwidth:
1624 cmd += " --bandwidth " + str( bandwidth )
1625 if lambdaAlloc:
1626 cmd += " --lambda "
1627 if ipProto:
1628 cmd += " --ipProto " + str( ipProto )
1629 if ipSrc:
1630 cmd += " --ipSrc " + str( ipSrc )
1631 if ipDst:
1632 cmd += " --ipDst " + str( ipDst )
1633 if tcpSrc:
1634 cmd += " --tcpSrc " + str( tcpSrc )
1635 if tcpDst:
1636 cmd += " --tcpDst " + str( tcpDst )
1637 if setEthSrc:
1638 cmd += " --setEthSrc " + str( setEthSrc )
1639 if setEthDst:
1640 cmd += " --setEthDst " + str( setEthDst )
1641 if vlanId:
1642 cmd += " -v " + str( vlanId )
1643 if setVlan:
1644 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001645 if partial:
1646 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001647 if encap:
1648 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001649
1650 # Check whether the user appended the port
1651 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001652
kelvin-onlabb9408212015-04-01 13:34:04 -07001653 if "/" in ingressDevice:
1654 cmd += " " + str( ingressDevice )
1655 else:
1656 if not portIngress:
1657 main.log.error( "You must specify " +
1658 "the Ingress port" )
1659 return main.FALSE
1660
1661 cmd += " " +\
1662 str( ingressDevice ) + "/" +\
1663 str( portIngress )
1664
1665 if portEgressList is None:
1666 for egressDevice in egressDeviceList:
1667 if "/" in egressDevice:
1668 cmd += " " + str( egressDevice )
1669 else:
1670 main.log.error( "You must specify " +
1671 "the egress port" )
1672 # TODO: perhaps more meaningful return
1673 return main.FALSE
1674 else:
1675 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001676 for egressDevice, portEgress in zip( egressDeviceList,
1677 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001678 cmd += " " + \
1679 str( egressDevice ) + "/" +\
1680 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001681 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001682 main.log.error( "Device list and port list does not " +
1683 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001684 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001685 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001686 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001687 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001688 # If error, return error message
1689 if re.search( "Error", handle ):
1690 main.log.error( "Error in adding singlepoint-to-multipoint " +
1691 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001692 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001693 else:
1694 match = re.search('id=0x([\da-f]+),', handle)
1695 if match:
1696 return match.group()[3:-1]
1697 else:
1698 main.log.error( "Error, intent ID not found" )
1699 return None
Jon Hallc6793552016-01-19 14:18:37 -08001700 except AssertionError:
1701 main.log.exception( "" )
1702 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001703 except TypeError:
1704 main.log.exception( self.name + ": Object not as expected" )
1705 return None
shahshreyad0c80432014-12-04 16:56:05 -08001706 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001707 main.log.error( self.name + ": EOF exception found" )
1708 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001709 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001710 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001711 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001712 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001713
Hari Krishna9e232602015-04-13 17:29:08 -07001714 def addMplsIntent(
1715 self,
1716 ingressDevice,
1717 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001718 ingressPort="",
1719 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001720 ethType="",
1721 ethSrc="",
1722 ethDst="",
1723 bandwidth="",
1724 lambdaAlloc=False,
1725 ipProto="",
1726 ipSrc="",
1727 ipDst="",
1728 tcpSrc="",
1729 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001730 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001731 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001732 priority=""):
1733 """
1734 Required:
1735 * ingressDevice: device id of ingress device
1736 * egressDevice: device id of egress device
1737 Optional:
1738 * ethType: specify ethType
1739 * ethSrc: specify ethSrc ( i.e. src mac addr )
1740 * ethDst: specify ethDst ( i.e. dst mac addr )
1741 * bandwidth: specify bandwidth capacity of link
1742 * lambdaAlloc: if True, intent will allocate lambda
1743 for the specified intent
1744 * ipProto: specify ip protocol
1745 * ipSrc: specify ip source address
1746 * ipDst: specify ip destination address
1747 * tcpSrc: specify tcp source port
1748 * tcpDst: specify tcp destination port
1749 * ingressLabel: Ingress MPLS label
1750 * egressLabel: Egress MPLS label
1751 Description:
1752 Adds MPLS intent by
1753 specifying device id's and optional fields
1754 Returns:
1755 A string of the intent id or None on error
1756
1757 NOTE: This function may change depending on the
1758 options developers provide for MPLS
1759 intent via cli
1760 """
1761 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001762 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001763
Jeremy Songsterff553672016-05-12 17:06:23 -07001764 if ethType:
1765 cmd += " --ethType " + str( ethType )
1766 if ethSrc:
1767 cmd += " --ethSrc " + str( ethSrc )
1768 if ethDst:
1769 cmd += " --ethDst " + str( ethDst )
1770 if bandwidth:
1771 cmd += " --bandwidth " + str( bandwidth )
1772 if lambdaAlloc:
1773 cmd += " --lambda "
1774 if ipProto:
1775 cmd += " --ipProto " + str( ipProto )
1776 if ipSrc:
1777 cmd += " --ipSrc " + str( ipSrc )
1778 if ipDst:
1779 cmd += " --ipDst " + str( ipDst )
1780 if tcpSrc:
1781 cmd += " --tcpSrc " + str( tcpSrc )
1782 if tcpDst:
1783 cmd += " --tcpDst " + str( tcpDst )
1784 if ingressLabel:
1785 cmd += " --ingressLabel " + str( ingressLabel )
1786 if egressLabel:
1787 cmd += " --egressLabel " + str( egressLabel )
1788 if priority:
1789 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001790
1791 # Check whether the user appended the port
1792 # or provided it as an input
1793 if "/" in ingressDevice:
1794 cmd += " " + str( ingressDevice )
1795 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001796 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001797 main.log.error( "You must specify the ingress port" )
1798 return None
1799
1800 cmd += " " + \
1801 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001802 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001803
1804 if "/" in egressDevice:
1805 cmd += " " + str( egressDevice )
1806 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001807 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001808 main.log.error( "You must specify the egress port" )
1809 return None
1810
1811 cmd += " " +\
1812 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001813 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001814
1815 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001816 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001817 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001818 # If error, return error message
1819 if re.search( "Error", handle ):
1820 main.log.error( "Error in adding mpls intent" )
1821 return None
1822 else:
1823 # TODO: print out all the options in this message?
1824 main.log.info( "MPLS intent installed between " +
1825 str( ingressDevice ) + " and " +
1826 str( egressDevice ) )
1827 match = re.search('id=0x([\da-f]+),', handle)
1828 if match:
1829 return match.group()[3:-1]
1830 else:
1831 main.log.error( "Error, intent ID not found" )
1832 return None
Jon Hallc6793552016-01-19 14:18:37 -08001833 except AssertionError:
1834 main.log.exception( "" )
1835 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001836 except TypeError:
1837 main.log.exception( self.name + ": Object not as expected" )
1838 return None
1839 except pexpect.EOF:
1840 main.log.error( self.name + ": EOF exception found" )
1841 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001842 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001843 except Exception:
1844 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001845 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001846
Jon Hallefbd9792015-03-05 16:11:36 -08001847 def removeIntent( self, intentId, app='org.onosproject.cli',
1848 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001849 """
shahshreya1c818fc2015-02-26 13:44:08 -08001850 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001851 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001852 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001853 -p or --purge: Purge the intent from the store after removal
1854
Jon Halle3f39ff2015-01-13 11:50:53 -08001855 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001856 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001857 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001858 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001859 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001860 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001861 if purge:
1862 cmdStr += " -p"
1863 if sync:
1864 cmdStr += " -s"
1865
1866 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001867 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001868 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001869 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001870 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001871 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001872 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001873 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001874 # TODO: Should this be main.TRUE
1875 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001876 except AssertionError:
1877 main.log.exception( "" )
1878 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001879 except TypeError:
1880 main.log.exception( self.name + ": Object not as expected" )
1881 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001882 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001883 main.log.error( self.name + ": EOF exception found" )
1884 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001885 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001886 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001887 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001888 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04001889
YPZhangfebf7302016-05-24 16:45:56 -07001890 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001891 """
1892 Description:
1893 Remove all the intents
1894 Optional args:-
1895 -s or --sync: Waits for the removal before returning
1896 -p or --purge: Purge the intent from the store after removal
1897 Returns:
1898 Returns main.TRUE if all intents are removed, otherwise returns
1899 main.FALSE; Returns None for exception
1900 """
1901 try:
1902 cmdStr = "remove-intent"
1903 if purge:
1904 cmdStr += " -p"
1905 if sync:
1906 cmdStr += " -s"
1907
1908 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001909 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001910 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08001911 assert "Command not found:" not in handle, handle
1912 if re.search( "Error", handle ):
1913 main.log.error( "Error in removing intent" )
1914 return main.FALSE
1915 else:
1916 return main.TRUE
1917 except AssertionError:
1918 main.log.exception( "" )
1919 return None
1920 except TypeError:
1921 main.log.exception( self.name + ": Object not as expected" )
1922 return None
1923 except pexpect.EOF:
1924 main.log.error( self.name + ": EOF exception found" )
1925 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001926 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001927 except Exception:
1928 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001929 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001930
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001931 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001932 """
1933 Purges all WITHDRAWN Intents
1934 """
1935 try:
1936 cmdStr = "purge-intents"
1937 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001938 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001939 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001940 if re.search( "Error", handle ):
1941 main.log.error( "Error in purging intents" )
1942 return main.FALSE
1943 else:
1944 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001945 except AssertionError:
1946 main.log.exception( "" )
1947 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001948 except TypeError:
1949 main.log.exception( self.name + ": Object not as expected" )
1950 return None
1951 except pexpect.EOF:
1952 main.log.error( self.name + ": EOF exception found" )
1953 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001954 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07001955 except Exception:
1956 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001957 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07001958
kelvin-onlabd3b64892015-01-20 13:26:24 -08001959 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001960 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001961 NOTE: This method should be used after installing application:
1962 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001963 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001964 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001965 Description:
1966 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001967 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001968 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001969 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001970 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001971 cmdStr += " -j"
1972 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001973 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001974 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001975 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001976 except AssertionError:
1977 main.log.exception( "" )
1978 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001979 except TypeError:
1980 main.log.exception( self.name + ": Object not as expected" )
1981 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001982 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001983 main.log.error( self.name + ": EOF exception found" )
1984 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001985 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001986 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001987 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001988 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08001989
pingping-lin54b03372015-08-13 14:43:10 -07001990 def ipv4RouteNumber( self ):
1991 """
1992 NOTE: This method should be used after installing application:
1993 onos-app-sdnip
1994 Description:
1995 Obtain the total IPv4 routes number in the system
1996 """
1997 try:
Pratik Parab57963572017-05-09 11:37:54 -07001998 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07001999 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002000 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002001 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002002 jsonResult = json.loads( handle )
Pratik Parab57963572017-05-09 11:37:54 -07002003 return len(jsonResult['routes4'])
Jon Hallc6793552016-01-19 14:18:37 -08002004 except AssertionError:
2005 main.log.exception( "" )
2006 return None
2007 except ( TypeError, ValueError ):
2008 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002009 return None
2010 except pexpect.EOF:
2011 main.log.error( self.name + ": EOF exception found" )
2012 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002013 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002014 except Exception:
2015 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002016 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002017
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002018 #=============Function to check Bandwidth allocation========
2019 def allocations( self, jsonFormat = True, dollarSign = True ):
2020 """
2021 Description:
2022 Obtain Bandwidth Allocation Information from ONOS cli.
2023 """
2024 try:
2025 cmdStr = "allocations"
2026 if jsonFormat:
2027 cmdStr += " -j"
2028 handle = self.sendline( cmdStr, timeout=300, dollarSign=True )
2029 assert handle is not None, "Error in sendline"
2030 assert "Command not found:" not in handle, handle
2031 return handle
2032 except AssertionError:
2033 main.log.exception( "" )
2034 return None
2035 except ( TypeError, ValueError ):
2036 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2037 return None
2038 except pexpect.EOF:
2039 main.log.error( self.name + ": EOF exception found" )
2040 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002041 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002042 except Exception:
2043 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002044 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002045
pingping-lin8244a3b2015-09-16 13:36:56 -07002046 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002047 """
andrewonlabe6745342014-10-17 14:29:13 -04002048 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002049 Obtain intents from the ONOS cli.
2050 Optional:
2051 * jsonFormat: Enable output formatting in json, default to True
2052 * summary: Whether only output the intent summary, defaults to False
2053 * type: Only output a certain type of intent. This options is valid
2054 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002055 """
andrewonlabe6745342014-10-17 14:29:13 -04002056 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002057 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002058 if summary:
2059 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002060 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002061 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002062 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002063 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002064 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002065 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002066 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002067 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002068 else:
Jon Hallff566d52016-01-15 14:45:36 -08002069 intentType = ""
2070 # IF we want the summary of a specific intent type
2071 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002072 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002073 if intentType in jsonResult.keys():
2074 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002075 else:
Jon Hallff566d52016-01-15 14:45:36 -08002076 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002077 return handle
2078 else:
2079 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002080 except AssertionError:
2081 main.log.exception( "" )
2082 return None
2083 except ( TypeError, ValueError ):
2084 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002085 return None
2086 except pexpect.EOF:
2087 main.log.error( self.name + ": EOF exception found" )
2088 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002089 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002090 except Exception:
2091 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002092 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002093
kelvin-onlab54400a92015-02-26 18:05:51 -08002094 def getIntentState(self, intentsId, intentsJson=None):
2095 """
You Wangfdcbfc42016-05-16 12:16:53 -07002096 Description:
2097 Gets intent state. Accepts a single intent ID (string type) or a
2098 list of intent IDs.
2099 Parameters:
2100 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002101 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002102 Returns:
2103 Returns the state (string type) of the ID if a single intent ID is
2104 accepted.
2105 Returns a list of dictionaries if a list of intent IDs is accepted,
2106 and each dictionary maps 'id' to the Intent ID and 'state' to
2107 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002108 """
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002109
kelvin-onlab54400a92015-02-26 18:05:51 -08002110 try:
2111 state = "State is Undefined"
2112 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002113 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002114 else:
Jon Hallc6793552016-01-19 14:18:37 -08002115 rawJson = intentsJson
2116 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002117 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002118 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002119 if intentsId == intent[ 'id' ]:
2120 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002121 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002122 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002123 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002124 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002125 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002126 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002127 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002128 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002129 for intent in parsedIntentsJson:
2130 if intentsId[ i ] == intent[ 'id' ]:
2131 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002132 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002133 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002134 break
Jon Hallefbd9792015-03-05 16:11:36 -08002135 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002136 main.log.warn( "Could not find all intents in ONOS output" )
2137 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002138 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002139 else:
Jon Hall53158082017-05-18 11:17:00 -07002140 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002141 return None
Jon Hallc6793552016-01-19 14:18:37 -08002142 except ( TypeError, ValueError ):
2143 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002144 return None
2145 except pexpect.EOF:
2146 main.log.error( self.name + ": EOF exception found" )
2147 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002148 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002149 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002150 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002151 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002152
Jon Hallf539eb92017-05-22 17:18:42 -07002153 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002154 """
2155 Description:
2156 Check intents state
2157 Required:
2158 intentsId - List of intents ID to be checked
2159 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002160 expectedState - Check the expected state(s) of each intents
2161 state in the list.
2162 *NOTE: You can pass in a list of expected state,
2163 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002164 Return:
Jon Hall53158082017-05-18 11:17:00 -07002165 Returns main.TRUE only if all intent are the same as expected states,
2166 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002167 """
2168 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002169 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002170 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002171
2172 #intentsDict = self.getIntentState( intentsId )
2173 intentsDict = []
2174 for intent in json.loads( self.intents() ):
2175 if isinstance ( intentsId, types.StringType) \
2176 and intent.get('id') == intentsId:
2177 intentsDict.append(intent)
2178 elif isinstance ( intentsId, types.ListType ) \
2179 and any( intent.get( 'id' ) == ids for ids in intentsId ):
2180 intentsDict.append(intent)
2181
2182 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002183 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002184 "getting intents state" )
2185 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002186
2187 if isinstance( expectedState, types.StringType ):
2188 for intents in intentsDict:
2189 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002190 main.log.debug( self.name + " : Intent ID - " +
2191 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002192 " actual state = " +
2193 intents.get( 'state' )
2194 + " does not equal expected state = "
2195 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002196 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002197 elif isinstance( expectedState, types.ListType ):
2198 for intents in intentsDict:
2199 if not any( state == intents.get( 'state' ) for state in
2200 expectedState ):
2201 main.log.debug( self.name + " : Intent ID - " +
2202 intents.get( 'id' ) +
2203 " actual state = " +
2204 intents.get( 'state' ) +
2205 " does not equal expected states = "
2206 + str( expectedState ) )
2207 returnValue = main.FALSE
2208
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002209 if returnValue == main.TRUE:
2210 main.log.info( self.name + ": All " +
2211 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002212 " intents are in " + str( expectedState ) +
2213 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002214 return returnValue
2215 except TypeError:
2216 main.log.exception( self.name + ": Object not as expected" )
2217 return None
2218 except pexpect.EOF:
2219 main.log.error( self.name + ": EOF exception found" )
2220 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002221 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002222 except Exception:
2223 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002224 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002225
Jon Hallf539eb92017-05-22 17:18:42 -07002226 def compareBandwidthAllocations( self, expectedAllocations ):
2227 """
2228 Description:
2229 Compare the allocated bandwidth with the given allocations
2230 Required:
2231 expectedAllocations - The expected ONOS output of the allocations command
2232 Return:
2233 Returns main.TRUE only if all intent are the same as expected states,
2234 otherwise returns main.FALSE.
2235 """
2236 # FIXME: Convert these string comparisons to object comparisons
2237 try:
2238 returnValue = main.TRUE
2239 bandwidthFailed = False
2240 rawAlloc = self.allocations()
2241 expectedFormat = StringIO( expectedAllocations )
2242 ONOSOutput = StringIO( rawAlloc )
2243 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2244 str( expectedFormat ) ) )
2245
2246 for actual, expected in izip( ONOSOutput, expectedFormat ):
2247 actual = actual.rstrip()
2248 expected = expected.rstrip()
2249 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2250 if actual != expected and 'allocated' in actual and 'allocated' in expected:
2251 marker1 = actual.find('allocated')
2252 m1 = actual[:marker1]
2253 marker2 = expected.find('allocated')
2254 m2 = expected[:marker2]
2255 if m1 != m2:
2256 bandwidthFailed = True
2257 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2258 bandwidthFailed = True
2259 expectedFormat.close()
2260 ONOSOutput.close()
2261
2262 if bandwidthFailed:
2263 main.log.error("Bandwidth not allocated correctly using Intents!!")
2264 returnValue = main.FALSE
2265 return returnValue
2266 except TypeError:
2267 main.log.exception( self.name + ": Object not as expected" )
2268 return None
2269 except pexpect.EOF:
2270 main.log.error( self.name + ": EOF exception found" )
2271 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002272 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002273 except Exception:
2274 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002275 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002276
You Wang66518af2016-05-16 15:32:59 -07002277 def compareIntent( self, intentDict ):
2278 """
2279 Description:
2280 Compare the intent ids and states provided in the argument with all intents in ONOS
2281 Return:
2282 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2283 Arguments:
2284 intentDict: a dictionary which maps intent ids to intent states
2285 """
2286 try:
2287 intentsRaw = self.intents()
2288 intentsJson = json.loads( intentsRaw )
2289 intentDictONOS = {}
2290 for intent in intentsJson:
2291 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002292 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002293 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002294 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002295 str( len( intentDict ) ) + " expected and " +
2296 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002297 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002298 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002299 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002300 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2301 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002302 else:
2303 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2304 main.log.debug( self.name + ": intent ID - " + intentID +
2305 " expected state is " + intentDict[ intentID ] +
2306 " but actual state is " + intentDictONOS[ intentID ] )
2307 returnValue = main.FALSE
2308 intentDictONOS.pop( intentID )
2309 if len( intentDictONOS ) > 0:
2310 returnValue = main.FALSE
2311 for intentID in intentDictONOS.keys():
2312 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002313 if returnValue == main.TRUE:
2314 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2315 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002316 except KeyError:
2317 main.log.exception( self.name + ": KeyError exception found" )
2318 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002319 except ( TypeError, ValueError ):
2320 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002321 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002322 except pexpect.EOF:
2323 main.log.error( self.name + ": EOF exception found" )
2324 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002325 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002326 except Exception:
2327 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002328 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002329
YPZhang14a4aa92016-07-15 13:37:15 -07002330 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002331 """
2332 Description:
2333 Check the number of installed intents.
2334 Optional:
2335 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002336 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002337 Return:
2338 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2339 , otherwise, returns main.FALSE.
2340 """
2341
2342 try:
2343 cmd = "intents -s -j"
2344
2345 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002346 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002347 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002348 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002349 response = json.loads( response )
2350
2351 # get total and installed number, see if they are match
2352 allState = response.get( 'all' )
2353 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002354 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002355 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002356 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002357 return main.FALSE
2358
Jon Hallc6793552016-01-19 14:18:37 -08002359 except ( TypeError, ValueError ):
2360 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002361 return None
2362 except pexpect.EOF:
2363 main.log.error( self.name + ": EOF exception found" )
2364 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002365 if noExit:
2366 return main.FALSE
2367 else:
Devin Lim44075962017-08-11 10:56:37 -07002368 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002369 except pexpect.TIMEOUT:
2370 main.log.error( self.name + ": ONOS timeout" )
2371 return None
GlennRCed771242016-01-13 17:02:47 -08002372 except Exception:
2373 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002374 if noExit:
2375 return main.FALSE
2376 else:
Devin Lim44075962017-08-11 10:56:37 -07002377 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002378
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002379 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002380 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002381 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002382 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002383 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002384 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002385 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002386 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002387 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002388 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002389 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002390 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002391 if noCore:
2392 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002393 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002394 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002395 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002396 assert "Command not found:" not in handle, handle
2397 if re.search( "Error:", handle ):
2398 main.log.error( self.name + ": flows() response: " +
2399 str( handle ) )
2400 return handle
2401 except AssertionError:
2402 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002403 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002404 except TypeError:
2405 main.log.exception( self.name + ": Object not as expected" )
2406 return None
Jon Hallc6793552016-01-19 14:18:37 -08002407 except pexpect.TIMEOUT:
2408 main.log.error( self.name + ": ONOS timeout" )
2409 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002410 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002411 main.log.error( self.name + ": EOF exception found" )
2412 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002413 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002414 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002415 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002416 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002417
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002418 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002419 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002420 count = int( count ) if count else 0
2421 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002422
Jon Halle0f0b342017-04-18 11:43:47 -07002423 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002424 """
2425 Description:
GlennRCed771242016-01-13 17:02:47 -08002426 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002427 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2428 if the count of those states is 0, which means all current flows
2429 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002430 Optional:
GlennRCed771242016-01-13 17:02:47 -08002431 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002432 Return:
2433 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002434 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002435 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002436 """
2437 try:
GlennRCed771242016-01-13 17:02:47 -08002438 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2439 checkedStates = []
2440 statesCount = [0, 0, 0, 0]
2441 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002442 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002443 if rawFlows:
2444 # if we didn't get flows or flows function return None, we should return
2445 # main.Flase
2446 checkedStates.append( json.loads( rawFlows ) )
2447 else:
2448 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002449 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002450 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002451 try:
2452 statesCount[i] += int( c.get( "flowCount" ) )
2453 except TypeError:
2454 main.log.exception( "Json object not as expected" )
2455 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002456
GlennRCed771242016-01-13 17:02:47 -08002457 # We want to count PENDING_ADD if isPENDING is true
2458 if isPENDING:
2459 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2460 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002461 else:
GlennRCed771242016-01-13 17:02:47 -08002462 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2463 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002464 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002465 except ( TypeError, ValueError ):
2466 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002467 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002468
YPZhang240842b2016-05-17 12:00:50 -07002469 except AssertionError:
2470 main.log.exception( "" )
2471 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002472 except pexpect.TIMEOUT:
2473 main.log.error( self.name + ": ONOS timeout" )
2474 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002475 except pexpect.EOF:
2476 main.log.error( self.name + ": EOF exception found" )
2477 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002478 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002479 except Exception:
2480 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002481 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002482
GlennRCed771242016-01-13 17:02:47 -08002483 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002484 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002485 """
andrewonlab87852b02014-11-19 18:44:19 -05002486 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002487 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002488 a specific point-to-point intent definition
2489 Required:
GlennRCed771242016-01-13 17:02:47 -08002490 * ingress: specify source dpid
2491 * egress: specify destination dpid
2492 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002493 Optional:
GlennRCed771242016-01-13 17:02:47 -08002494 * offset: the keyOffset is where the next batch of intents
2495 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002496 * noExit: If set to True, TestON will not exit if any error when issus command
2497 * getResponse: If set to True, function will return ONOS response.
2498
GlennRCed771242016-01-13 17:02:47 -08002499 Returns: If failed to push test intents, it will returen None,
2500 if successful, return true.
2501 Timeout expection will return None,
2502 TypeError will return false
2503 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002504 """
andrewonlab87852b02014-11-19 18:44:19 -05002505 try:
GlennRCed771242016-01-13 17:02:47 -08002506 if background:
2507 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002508 else:
GlennRCed771242016-01-13 17:02:47 -08002509 back = ""
2510 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002511 ingress,
2512 egress,
2513 batchSize,
2514 offset,
2515 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002516 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002517 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002518 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002519 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002520 if getResponse:
2521 return response
2522
GlennRCed771242016-01-13 17:02:47 -08002523 # TODO: We should handle if there is failure in installation
2524 return main.TRUE
2525
Jon Hallc6793552016-01-19 14:18:37 -08002526 except AssertionError:
2527 main.log.exception( "" )
2528 return None
GlennRCed771242016-01-13 17:02:47 -08002529 except pexpect.TIMEOUT:
2530 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002531 return None
andrewonlab87852b02014-11-19 18:44:19 -05002532 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002533 main.log.error( self.name + ": EOF exception found" )
2534 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002535 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002536 except TypeError:
2537 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002538 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002539 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002540 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002541 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002542
YPZhangebf9eb52016-05-12 15:20:24 -07002543 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002544 """
2545 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002546 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002547 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002548 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002549 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002550 """
YPZhange3109a72016-02-02 11:25:37 -08002551
YPZhangb5d3f832016-01-23 22:54:26 -08002552 try:
YPZhange3109a72016-02-02 11:25:37 -08002553 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002554 cmd = "flows -c added"
2555 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2556 if rawFlows:
2557 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002558 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002559 for l in rawFlows:
2560 totalFlows += int(l.split("Count=")[1])
2561 else:
2562 main.log.error("Response not as expected!")
2563 return None
2564 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002565
You Wangd3cb2ce2016-05-16 14:01:24 -07002566 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002567 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002568 return None
2569 except pexpect.EOF:
2570 main.log.error( self.name + ": EOF exception found" )
2571 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002572 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002573 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002574 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002575 except pexpect.TIMEOUT:
2576 main.log.error( self.name + ": ONOS timeout" )
2577 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002578 except Exception:
2579 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002580 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002581 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002582 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002583
YPZhang14a4aa92016-07-15 13:37:15 -07002584 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002585 """
2586 Description:
2587 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002588 Optional:
2589 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002590 Return:
2591 The number of intents
2592 """
2593 try:
2594 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002595 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002596 if response is None:
2597 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002598 response = json.loads( response )
2599 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002600 except ( TypeError, ValueError ):
2601 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002602 return None
2603 except pexpect.EOF:
2604 main.log.error( self.name + ": EOF exception found" )
2605 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002606 if noExit:
2607 return -1
2608 else:
Devin Lim44075962017-08-11 10:56:37 -07002609 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002610 except Exception:
2611 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002612 if noExit:
2613 return -1
2614 else:
Devin Lim44075962017-08-11 10:56:37 -07002615 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002616
kelvin-onlabd3b64892015-01-20 13:26:24 -08002617 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002618 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002619 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002620 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002621 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002622 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002623 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002624 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002625 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002626 cmdStr += " -j"
2627 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002628 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002629 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002630 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002631 except AssertionError:
2632 main.log.exception( "" )
2633 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002634 except TypeError:
2635 main.log.exception( self.name + ": Object not as expected" )
2636 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002637 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002638 main.log.error( self.name + ": EOF exception found" )
2639 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002640 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002641 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002642 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002643 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002644
kelvin-onlabd3b64892015-01-20 13:26:24 -08002645 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002646 """
2647 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002648 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002649 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002650 """
andrewonlab867212a2014-10-22 20:13:38 -04002651 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002652 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002653 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002654 cmdStr += " -j"
2655 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002656 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002657 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002658 if handle:
2659 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002660 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002661 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002662 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002663 else:
2664 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002665 except AssertionError:
2666 main.log.exception( "" )
2667 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002668 except TypeError:
2669 main.log.exception( self.name + ": Object not as expected" )
2670 return None
andrewonlab867212a2014-10-22 20:13:38 -04002671 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002672 main.log.error( self.name + ": EOF exception found" )
2673 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002674 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002675 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002676 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002677 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002678
kelvin8ec71442015-01-15 16:57:00 -08002679 # Wrapper functions ****************
2680 # Wrapper functions use existing driver
2681 # functions and extends their use case.
2682 # For example, we may use the output of
2683 # a normal driver function, and parse it
2684 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002685
kelvin-onlabd3b64892015-01-20 13:26:24 -08002686 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002687 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002688 Description:
2689 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002690 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002691 try:
kelvin8ec71442015-01-15 16:57:00 -08002692 # Obtain output of intents function
Jon Hall6021e062017-01-30 11:10:06 -08002693 intentsStr = self.intents(jsonFormat=True)
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002694 if intentsStr is None:
2695 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002696 # Convert to a dictionary
2697 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002698 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002699 for intent in intents:
2700 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002701 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002702 except TypeError:
2703 main.log.exception( self.name + ": Object not as expected" )
2704 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002705 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002706 main.log.error( self.name + ": EOF exception found" )
2707 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002708 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002709 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002710 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002711 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002712
You Wang3c276252016-09-21 15:21:36 -07002713 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002714 """
2715 Determine the number of flow rules for the given device id that are
2716 in the added state
You Wang3c276252016-09-21 15:21:36 -07002717 Params:
2718 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002719 """
2720 try:
You Wang3c276252016-09-21 15:21:36 -07002721 if core:
2722 cmdStr = "flows any " + str( deviceId ) + " | " +\
2723 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2724 else:
2725 cmdStr = "flows any " + str( deviceId ) + " | " +\
2726 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002727 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002728 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002729 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002730 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002731 except AssertionError:
2732 main.log.exception( "" )
2733 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002734 except pexpect.EOF:
2735 main.log.error( self.name + ": EOF exception found" )
2736 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002737 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002738 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002739 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002740 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002741
kelvin-onlabd3b64892015-01-20 13:26:24 -08002742 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002743 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002744 Use 'devices' function to obtain list of all devices
2745 and parse the result to obtain a list of all device
2746 id's. Returns this list. Returns empty list if no
2747 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002748 List is ordered sequentially
2749
andrewonlab3e15ead2014-10-15 14:21:34 -04002750 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002751 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002752 the ids. By obtaining the list of device ids on the fly,
2753 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002754 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002755 try:
kelvin8ec71442015-01-15 16:57:00 -08002756 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002757 devicesStr = self.devices( jsonFormat=False )
2758 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002759
kelvin-onlabd3b64892015-01-20 13:26:24 -08002760 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002761 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002762 return idList
kelvin8ec71442015-01-15 16:57:00 -08002763
2764 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002765 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002766 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002767 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002768 # Split list further into arguments before and after string
2769 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002770 # append to idList
2771 for arg in tempList:
2772 idList.append( arg.split( "id=" )[ 1 ] )
2773 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002774
Jon Halld4d4b372015-01-28 16:02:41 -08002775 except TypeError:
2776 main.log.exception( self.name + ": Object not as expected" )
2777 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002778 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002779 main.log.error( self.name + ": EOF exception found" )
2780 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002781 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002782 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002783 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002784 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002785
kelvin-onlabd3b64892015-01-20 13:26:24 -08002786 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002787 """
andrewonlab7c211572014-10-15 16:45:20 -04002788 Uses 'nodes' function to obtain list of all nodes
2789 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002790 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002791 Returns:
2792 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002793 """
andrewonlab7c211572014-10-15 16:45:20 -04002794 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002795 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002796 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002797 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002798 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002799 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002800 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002801 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002802 nodesJson = json.loads( nodesStr )
2803 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002804 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002805 except ( TypeError, ValueError ):
2806 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002807 return None
andrewonlab7c211572014-10-15 16:45:20 -04002808 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002809 main.log.error( self.name + ": EOF exception found" )
2810 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002811 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002812 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002813 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002814 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002815
kelvin-onlabd3b64892015-01-20 13:26:24 -08002816 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002817 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002818 Return the first device from the devices api whose 'id' contains 'dpid'
2819 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002820 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002821 try:
kelvin8ec71442015-01-15 16:57:00 -08002822 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002823 return None
2824 else:
kelvin8ec71442015-01-15 16:57:00 -08002825 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002826 rawDevices = self.devices()
2827 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002828 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002829 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002830 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2831 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002832 return device
2833 return None
Jon Hallc6793552016-01-19 14:18:37 -08002834 except ( TypeError, ValueError ):
2835 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002836 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002837 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002838 main.log.error( self.name + ": EOF exception found" )
2839 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002840 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002841 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002842 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002843 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04002844
You Wang24139872016-05-03 11:48:47 -07002845 def getTopology( self, topologyOutput ):
2846 """
2847 Definition:
2848 Loads a json topology output
2849 Return:
2850 topology = current ONOS topology
2851 """
2852 import json
2853 try:
2854 # either onos:topology or 'topology' will work in CLI
2855 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002856 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002857 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002858 except ( TypeError, ValueError ):
2859 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2860 return None
You Wang24139872016-05-03 11:48:47 -07002861 except pexpect.EOF:
2862 main.log.error( self.name + ": EOF exception found" )
2863 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002864 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07002865 except Exception:
2866 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002867 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07002868
Flavio Castro82ee2f62016-06-07 15:04:12 -07002869 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002870 """
Jon Hallefbd9792015-03-05 16:11:36 -08002871 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002872 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002873 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002874
Flavio Castro82ee2f62016-06-07 15:04:12 -07002875 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002876 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002877 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002878 logLevel = level to log to.
2879 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002880
Jon Hallefbd9792015-03-05 16:11:36 -08002881 Returns: main.TRUE if the number of switches and links are correct,
2882 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002883 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002884 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002885 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002886 try:
You Wang13310252016-07-31 10:56:14 -07002887 summary = self.summary()
2888 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002889 except ( TypeError, ValueError ):
2890 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2891 return main.ERROR
2892 try:
2893 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07002894 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002895 return main.ERROR
2896 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002897 # Is the number of switches is what we expected
2898 devices = topology.get( 'devices', False )
2899 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002900 nodes = summary.get( 'nodes', False )
2901 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002902 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002903 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002904 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002905 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002906 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2907 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002908 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002909 output = output + "The number of links and switches match "\
2910 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002911 result = main.TRUE
2912 else:
You Wang24139872016-05-03 11:48:47 -07002913 output = output + \
2914 "The number of links and switches does not match " + \
2915 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002916 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002917 output = output + "\n ONOS sees %i devices" % int( devices )
2918 output = output + " (%i expected) " % int( numoswitch )
2919 output = output + "and %i links " % int( links )
2920 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002921 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002922 output = output + "and %i controllers " % int( nodes )
2923 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002924 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002925 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002926 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002927 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002928 else:
You Wang24139872016-05-03 11:48:47 -07002929 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002930 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002931 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002932 main.log.error( self.name + ": EOF exception found" )
2933 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002934 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002935 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002936 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002937 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002938
kelvin-onlabd3b64892015-01-20 13:26:24 -08002939 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002940 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002941 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002942 deviceId must be the id of a device as seen in the onos devices command
2943 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002944 role must be either master, standby, or none
2945
Jon Halle3f39ff2015-01-13 11:50:53 -08002946 Returns:
2947 main.TRUE or main.FALSE based on argument verification and
2948 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002949 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002950 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002951 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002952 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002953 cmdStr = "device-role " +\
2954 str( deviceId ) + " " +\
2955 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002956 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002957 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002958 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002959 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002960 if re.search( "Error", handle ):
2961 # end color output to escape any colours
2962 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002963 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002964 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002965 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002966 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002967 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002968 main.log.error( "Invalid 'role' given to device_role(). " +
2969 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002970 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002971 except AssertionError:
2972 main.log.exception( "" )
2973 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002974 except TypeError:
2975 main.log.exception( self.name + ": Object not as expected" )
2976 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002977 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002978 main.log.error( self.name + ": EOF exception found" )
2979 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002980 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002981 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002982 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002983 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002984
kelvin-onlabd3b64892015-01-20 13:26:24 -08002985 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002986 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002987 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002988 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002989 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002990 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002991 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002992 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002993 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002994 cmdStr += " -j"
2995 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002996 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002997 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002998 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002999 except AssertionError:
3000 main.log.exception( "" )
3001 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003002 except TypeError:
3003 main.log.exception( self.name + ": Object not as expected" )
3004 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003005 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003006 main.log.error( self.name + ": EOF exception found" )
3007 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003008 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003009 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003010 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003011 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003012
kelvin-onlabd3b64892015-01-20 13:26:24 -08003013 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003014 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003015 CLI command to get the current leader for the Election test application
3016 NOTE: Requires installation of the onos-app-election feature
3017 Returns: Node IP of the leader if one exists
3018 None if none exists
3019 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003020 """
Jon Hall94fd0472014-12-08 11:52:42 -08003021 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003022 cmdStr = "election-test-leader"
3023 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003024 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003025 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003026 # Leader
3027 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003028 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003029 nodeSearch = re.search( leaderPattern, response )
3030 if nodeSearch:
3031 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003032 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003033 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003034 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003035 # no leader
3036 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003037 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003038 nullSearch = re.search( nullPattern, response )
3039 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003040 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003041 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003042 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003043 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003044 main.log.error( "Error in electionTestLeader on " + self.name +
3045 ": " + "unexpected response" )
3046 main.log.error( repr( response ) )
3047 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003048 except AssertionError:
3049 main.log.exception( "" )
3050 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003051 except TypeError:
3052 main.log.exception( self.name + ": Object not as expected" )
3053 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003054 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003055 main.log.error( self.name + ": EOF exception found" )
3056 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003057 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003058 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003059 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003060 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003061
kelvin-onlabd3b64892015-01-20 13:26:24 -08003062 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003063 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003064 CLI command to run for leadership of the Election test application.
3065 NOTE: Requires installation of the onos-app-election feature
3066 Returns: Main.TRUE on success
3067 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003068 """
Jon Hall94fd0472014-12-08 11:52:42 -08003069 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003070 cmdStr = "election-test-run"
3071 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003072 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003073 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003074 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003075 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003076 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003077 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003078 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003079 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003080 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003081 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003082 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003083 main.log.error( "Error in electionTestRun on " + self.name +
3084 ": " + "unexpected response" )
3085 main.log.error( repr( response ) )
3086 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003087 except AssertionError:
3088 main.log.exception( "" )
3089 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003090 except TypeError:
3091 main.log.exception( self.name + ": Object not as expected" )
3092 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003094 main.log.error( self.name + ": EOF exception found" )
3095 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003096 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003097 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003098 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003099 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003100
kelvin-onlabd3b64892015-01-20 13:26:24 -08003101 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003102 """
Jon Hall94fd0472014-12-08 11:52:42 -08003103 * CLI command to withdraw the local node from leadership election for
3104 * the Election test application.
3105 #NOTE: Requires installation of the onos-app-election feature
3106 Returns: Main.TRUE on success
3107 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003108 """
Jon Hall94fd0472014-12-08 11:52:42 -08003109 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003110 cmdStr = "election-test-withdraw"
3111 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003112 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003113 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003114 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003115 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003116 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003117 if re.search( successPattern, response ):
3118 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003119 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003120 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003121 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003122 main.log.error( "Error in electionTestWithdraw on " +
3123 self.name + ": " + "unexpected response" )
3124 main.log.error( repr( response ) )
3125 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003126 except AssertionError:
3127 main.log.exception( "" )
3128 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003129 except TypeError:
3130 main.log.exception( self.name + ": Object not as expected" )
3131 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003132 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003133 main.log.error( self.name + ": EOF exception found" )
3134 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003135 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003136 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003137 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003138 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003139
kelvin8ec71442015-01-15 16:57:00 -08003140 def getDevicePortsEnabledCount( self, dpid ):
3141 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003142 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003143 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003144 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003145 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003146 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3147 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003148 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003149 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003150 if re.search( "No such device", output ):
3151 main.log.error( "Error in getting ports" )
3152 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003153 return output
Jon Hallc6793552016-01-19 14:18:37 -08003154 except AssertionError:
3155 main.log.exception( "" )
3156 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003157 except TypeError:
3158 main.log.exception( self.name + ": Object not as expected" )
3159 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003160 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003161 main.log.error( self.name + ": EOF exception found" )
3162 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003163 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003164 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003165 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003166 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003167
kelvin8ec71442015-01-15 16:57:00 -08003168 def getDeviceLinksActiveCount( self, dpid ):
3169 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003170 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003171 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003172 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003173 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003174 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3175 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003176 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003177 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003178 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003179 main.log.error( "Error in getting ports " )
3180 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003181 return output
Jon Hallc6793552016-01-19 14:18:37 -08003182 except AssertionError:
3183 main.log.exception( "" )
3184 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003185 except TypeError:
3186 main.log.exception( self.name + ": Object not as expected" )
3187 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003188 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003189 main.log.error( self.name + ": EOF exception found" )
3190 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003191 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003192 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003193 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003194 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003195
kelvin8ec71442015-01-15 16:57:00 -08003196 def getAllIntentIds( self ):
3197 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003198 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003199 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003200 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003201 cmdStr = "onos:intents | grep id="
3202 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003203 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003204 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003205 if re.search( "Error", output ):
3206 main.log.error( "Error in getting ports" )
3207 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003208 return output
Jon Hallc6793552016-01-19 14:18:37 -08003209 except AssertionError:
3210 main.log.exception( "" )
3211 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003212 except TypeError:
3213 main.log.exception( self.name + ": Object not as expected" )
3214 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003215 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003216 main.log.error( self.name + ": EOF exception found" )
3217 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003218 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003219 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003220 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003221 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003222
Jon Hall73509952015-02-24 16:42:56 -08003223 def intentSummary( self ):
3224 """
Jon Hallefbd9792015-03-05 16:11:36 -08003225 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003226 """
3227 try:
3228 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003229 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003230 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003231 states.append( intent.get( 'state', None ) )
3232 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003233 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003234 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003235 except ( TypeError, ValueError ):
3236 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003237 return None
3238 except pexpect.EOF:
3239 main.log.error( self.name + ": EOF exception found" )
3240 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003241 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003242 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003243 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003244 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003245
Jon Hall61282e32015-03-19 11:34:11 -07003246 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003247 """
3248 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003249 Optional argument:
3250 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003251 """
Jon Hall63604932015-02-26 17:09:50 -08003252 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003253 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003254 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003255 cmdStr += " -j"
3256 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003257 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003258 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003259 return output
Jon Hallc6793552016-01-19 14:18:37 -08003260 except AssertionError:
3261 main.log.exception( "" )
3262 return None
Jon Hall63604932015-02-26 17:09:50 -08003263 except TypeError:
3264 main.log.exception( self.name + ": Object not as expected" )
3265 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003266 except pexpect.EOF:
3267 main.log.error( self.name + ": EOF exception found" )
3268 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003269 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003270 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003271 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003272 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003273
acsmarsa4a4d1e2015-07-10 16:01:24 -07003274 def leaderCandidates( self, jsonFormat=True ):
3275 """
3276 Returns the output of the leaders -c command.
3277 Optional argument:
3278 * jsonFormat - boolean indicating if you want output in json
3279 """
3280 try:
3281 cmdStr = "onos:leaders -c"
3282 if jsonFormat:
3283 cmdStr += " -j"
3284 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003285 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003286 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003287 return output
Jon Hallc6793552016-01-19 14:18:37 -08003288 except AssertionError:
3289 main.log.exception( "" )
3290 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003291 except TypeError:
3292 main.log.exception( self.name + ": Object not as expected" )
3293 return None
3294 except pexpect.EOF:
3295 main.log.error( self.name + ": EOF exception found" )
3296 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003297 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003298 except Exception:
3299 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003300 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003301
Jon Hallc6793552016-01-19 14:18:37 -08003302 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003303 """
3304 Returns a list in format [leader,candidate1,candidate2,...] for a given
3305 topic parameter and an empty list if the topic doesn't exist
3306 If no leader is elected leader in the returned list will be "none"
3307 Returns None if there is a type error processing the json object
3308 """
3309 try:
Jon Hall6e709752016-02-01 13:38:46 -08003310 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003311 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003312 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003313 assert "Command not found:" not in rawOutput, rawOutput
3314 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003315 results = []
3316 for dict in output:
3317 if dict["topic"] == topic:
3318 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003319 candidates = re.split( ", ", dict["candidates"][1:-1] )
3320 results.append( leader )
3321 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003322 return results
Jon Hallc6793552016-01-19 14:18:37 -08003323 except AssertionError:
3324 main.log.exception( "" )
3325 return None
3326 except ( TypeError, ValueError ):
3327 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003328 return None
3329 except pexpect.EOF:
3330 main.log.error( self.name + ": EOF exception found" )
3331 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003332 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003333 except Exception:
3334 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003335 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003336
Jon Hall61282e32015-03-19 11:34:11 -07003337 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003338 """
3339 Returns the output of the intent Pending map.
3340 """
Jon Hall63604932015-02-26 17:09:50 -08003341 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003342 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003343 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003344 cmdStr += " -j"
3345 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003346 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003347 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003348 return output
Jon Hallc6793552016-01-19 14:18:37 -08003349 except AssertionError:
3350 main.log.exception( "" )
3351 return None
Jon Hall63604932015-02-26 17:09:50 -08003352 except TypeError:
3353 main.log.exception( self.name + ": Object not as expected" )
3354 return None
3355 except pexpect.EOF:
3356 main.log.error( self.name + ": EOF exception found" )
3357 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003358 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003359 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003360 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003361 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003362
Jon Hall2c8959e2016-12-16 12:17:34 -08003363 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003364 """
3365 Returns the output of the raft partitions command for ONOS.
3366 """
Jon Hall61282e32015-03-19 11:34:11 -07003367 # Sample JSON
3368 # {
3369 # "leader": "tcp://10.128.30.11:7238",
3370 # "members": [
3371 # "tcp://10.128.30.11:7238",
3372 # "tcp://10.128.30.17:7238",
3373 # "tcp://10.128.30.13:7238",
3374 # ],
3375 # "name": "p1",
3376 # "term": 3
3377 # },
Jon Hall63604932015-02-26 17:09:50 -08003378 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003379 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003380 if candidates:
3381 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003382 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003383 cmdStr += " -j"
3384 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003385 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003386 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003387 return output
Jon Hallc6793552016-01-19 14:18:37 -08003388 except AssertionError:
3389 main.log.exception( "" )
3390 return None
Jon Hall63604932015-02-26 17:09:50 -08003391 except TypeError:
3392 main.log.exception( self.name + ": Object not as expected" )
3393 return None
3394 except pexpect.EOF:
3395 main.log.error( self.name + ": EOF exception found" )
3396 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003397 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003398 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003399 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003400 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003401
Jon Halle9f909e2016-09-23 10:43:12 -07003402 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003403 """
3404 Returns the output of the apps command for ONOS. This command lists
3405 information about installed ONOS applications
3406 """
3407 # Sample JSON object
3408 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3409 # "description":"ONOS OpenFlow protocol southbound providers",
3410 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3411 # "features":"[onos-openflow]","state":"ACTIVE"}]
3412 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003413 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003414 if summary:
3415 cmdStr += " -s"
3416 if active:
3417 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003418 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003419 cmdStr += " -j"
3420 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003421 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003422 assert "Command not found:" not in output, output
3423 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003424 return output
Jon Hallbe379602015-03-24 13:39:32 -07003425 # FIXME: look at specific exceptions/Errors
3426 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003427 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003428 return None
3429 except TypeError:
3430 main.log.exception( self.name + ": Object not as expected" )
3431 return None
3432 except pexpect.EOF:
3433 main.log.error( self.name + ": EOF exception found" )
3434 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003435 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003436 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003437 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003438 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003439
Jon Hall146f1522015-03-24 15:33:24 -07003440 def appStatus( self, appName ):
3441 """
3442 Uses the onos:apps cli command to return the status of an application.
3443 Returns:
3444 "ACTIVE" - If app is installed and activated
3445 "INSTALLED" - If app is installed and deactivated
3446 "UNINSTALLED" - If app is not installed
3447 None - on error
3448 """
Jon Hall146f1522015-03-24 15:33:24 -07003449 try:
3450 if not isinstance( appName, types.StringType ):
3451 main.log.error( self.name + ".appStatus(): appName must be" +
3452 " a string" )
3453 return None
3454 output = self.apps( jsonFormat=True )
3455 appsJson = json.loads( output )
3456 state = None
3457 for app in appsJson:
3458 if appName == app.get('name'):
3459 state = app.get('state')
3460 break
3461 if state == "ACTIVE" or state == "INSTALLED":
3462 return state
3463 elif state is None:
Jon Hall8bafdc02017-09-05 11:36:26 -07003464 main.log.warn( "{} app not found", appName )
Jon Hall146f1522015-03-24 15:33:24 -07003465 return "UNINSTALLED"
3466 elif state:
3467 main.log.error( "Unexpected state from 'onos:apps': " +
3468 str( state ) )
3469 return state
Jon Hallc6793552016-01-19 14:18:37 -08003470 except ( TypeError, ValueError ):
3471 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003472 return None
3473 except pexpect.EOF:
3474 main.log.error( self.name + ": EOF exception found" )
3475 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003476 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003477 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003478 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003479 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003480
Jon Hallbe379602015-03-24 13:39:32 -07003481 def app( self, appName, option ):
3482 """
3483 Interacts with the app command for ONOS. This command manages
3484 application inventory.
3485 """
Jon Hallbe379602015-03-24 13:39:32 -07003486 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003487 # Validate argument types
3488 valid = True
3489 if not isinstance( appName, types.StringType ):
3490 main.log.error( self.name + ".app(): appName must be a " +
3491 "string" )
3492 valid = False
3493 if not isinstance( option, types.StringType ):
3494 main.log.error( self.name + ".app(): option must be a string" )
3495 valid = False
3496 if not valid:
3497 return main.FALSE
3498 # Validate Option
3499 option = option.lower()
3500 # NOTE: Install may become a valid option
3501 if option == "activate":
3502 pass
3503 elif option == "deactivate":
3504 pass
3505 elif option == "uninstall":
3506 pass
3507 else:
3508 # Invalid option
3509 main.log.error( "The ONOS app command argument only takes " +
3510 "the values: (activate|deactivate|uninstall)" +
3511 "; was given '" + option + "'")
3512 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003513 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003514 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003515 assert output is not None, "Error in sendline"
3516 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003517 if "Error executing command" in output:
3518 main.log.error( "Error in processing onos:app command: " +
3519 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003520 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003521 elif "No such application" in output:
3522 main.log.error( "The application '" + appName +
3523 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003524 return main.FALSE
3525 elif "Command not found:" in output:
3526 main.log.error( "Error in processing onos:app command: " +
3527 str( output ) )
3528 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003529 elif "Unsupported command:" in output:
3530 main.log.error( "Incorrect command given to 'app': " +
3531 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003532 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003533 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003534 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003535 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003536 except AssertionError:
3537 main.log.exception( self.name + ": AssertionError exception found" )
3538 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003539 except TypeError:
3540 main.log.exception( self.name + ": Object not as expected" )
3541 return main.ERROR
3542 except pexpect.EOF:
3543 main.log.error( self.name + ": EOF exception found" )
3544 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003545 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003546 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003547 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003548 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003549
Jon Hallbd16b922015-03-26 17:53:15 -07003550 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003551 """
3552 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003553 appName is the hierarchical app name, not the feature name
3554 If check is True, method will check the status of the app after the
3555 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003556 Returns main.TRUE if the command was successfully sent
3557 main.FALSE if the cli responded with an error or given
3558 incorrect input
3559 """
3560 try:
3561 if not isinstance( appName, types.StringType ):
3562 main.log.error( self.name + ".activateApp(): appName must be" +
3563 " a string" )
3564 return main.FALSE
3565 status = self.appStatus( appName )
3566 if status == "INSTALLED":
3567 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003568 if check and response == main.TRUE:
3569 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003570 status = self.appStatus( appName )
3571 if status == "ACTIVE":
3572 return main.TRUE
3573 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003574 main.log.debug( "The state of application " +
3575 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003576 time.sleep( 1 )
3577 return main.FALSE
3578 else: # not 'check' or command didn't succeed
3579 return response
Jon Hall146f1522015-03-24 15:33:24 -07003580 elif status == "ACTIVE":
3581 return main.TRUE
3582 elif status == "UNINSTALLED":
3583 main.log.error( self.name + ": Tried to activate the " +
3584 "application '" + appName + "' which is not " +
3585 "installed." )
3586 else:
3587 main.log.error( "Unexpected return value from appStatus: " +
3588 str( status ) )
3589 return main.ERROR
3590 except TypeError:
3591 main.log.exception( self.name + ": Object not as expected" )
3592 return main.ERROR
3593 except pexpect.EOF:
3594 main.log.error( self.name + ": EOF exception found" )
3595 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003596 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003597 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003598 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003599 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003600
Jon Hallbd16b922015-03-26 17:53:15 -07003601 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003602 """
3603 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003604 appName is the hierarchical app name, not the feature name
3605 If check is True, method will check the status of the app after the
3606 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003607 Returns main.TRUE if the command was successfully sent
3608 main.FALSE if the cli responded with an error or given
3609 incorrect input
3610 """
3611 try:
3612 if not isinstance( appName, types.StringType ):
3613 main.log.error( self.name + ".deactivateApp(): appName must " +
3614 "be a string" )
3615 return main.FALSE
3616 status = self.appStatus( appName )
3617 if status == "INSTALLED":
3618 return main.TRUE
3619 elif status == "ACTIVE":
3620 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003621 if check and response == main.TRUE:
3622 for i in range(10): # try 10 times then give up
3623 status = self.appStatus( appName )
3624 if status == "INSTALLED":
3625 return main.TRUE
3626 else:
3627 time.sleep( 1 )
3628 return main.FALSE
3629 else: # not check or command didn't succeed
3630 return response
Jon Hall146f1522015-03-24 15:33:24 -07003631 elif status == "UNINSTALLED":
3632 main.log.warn( self.name + ": Tried to deactivate the " +
3633 "application '" + appName + "' which is not " +
3634 "installed." )
3635 return main.TRUE
3636 else:
3637 main.log.error( "Unexpected return value from appStatus: " +
3638 str( status ) )
3639 return main.ERROR
3640 except TypeError:
3641 main.log.exception( self.name + ": Object not as expected" )
3642 return main.ERROR
3643 except pexpect.EOF:
3644 main.log.error( self.name + ": EOF exception found" )
3645 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003646 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003647 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003648 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003649 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003650
Jon Hallbd16b922015-03-26 17:53:15 -07003651 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003652 """
3653 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003654 appName is the hierarchical app name, not the feature name
3655 If check is True, method will check the status of the app after the
3656 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003657 Returns main.TRUE if the command was successfully sent
3658 main.FALSE if the cli responded with an error or given
3659 incorrect input
3660 """
3661 # TODO: check with Thomas about the state machine for apps
3662 try:
3663 if not isinstance( appName, types.StringType ):
3664 main.log.error( self.name + ".uninstallApp(): appName must " +
3665 "be a string" )
3666 return main.FALSE
3667 status = self.appStatus( appName )
3668 if status == "INSTALLED":
3669 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003670 if check and response == main.TRUE:
3671 for i in range(10): # try 10 times then give up
3672 status = self.appStatus( appName )
3673 if status == "UNINSTALLED":
3674 return main.TRUE
3675 else:
3676 time.sleep( 1 )
3677 return main.FALSE
3678 else: # not check or command didn't succeed
3679 return response
Jon Hall146f1522015-03-24 15:33:24 -07003680 elif status == "ACTIVE":
3681 main.log.warn( self.name + ": Tried to uninstall the " +
3682 "application '" + appName + "' which is " +
3683 "currently active." )
3684 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003685 if check and response == main.TRUE:
3686 for i in range(10): # try 10 times then give up
3687 status = self.appStatus( appName )
3688 if status == "UNINSTALLED":
3689 return main.TRUE
3690 else:
3691 time.sleep( 1 )
3692 return main.FALSE
3693 else: # not check or command didn't succeed
3694 return response
Jon Hall146f1522015-03-24 15:33:24 -07003695 elif status == "UNINSTALLED":
3696 return main.TRUE
3697 else:
3698 main.log.error( "Unexpected return value from appStatus: " +
3699 str( status ) )
3700 return main.ERROR
3701 except TypeError:
3702 main.log.exception( self.name + ": Object not as expected" )
3703 return main.ERROR
3704 except pexpect.EOF:
3705 main.log.error( self.name + ": EOF exception found" )
3706 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003707 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003708 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003709 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003710 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003711
3712 def appIDs( self, jsonFormat=True ):
3713 """
3714 Show the mappings between app id and app names given by the 'app-ids'
3715 cli command
3716 """
3717 try:
3718 cmdStr = "app-ids"
3719 if jsonFormat:
3720 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003721 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003722 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003723 assert "Command not found:" not in output, output
3724 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003725 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003726 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003727 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003728 return None
3729 except TypeError:
3730 main.log.exception( self.name + ": Object not as expected" )
3731 return None
3732 except pexpect.EOF:
3733 main.log.error( self.name + ": EOF exception found" )
3734 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003735 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003736 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003737 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003738 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003739
3740 def appToIDCheck( self ):
3741 """
3742 This method will check that each application's ID listed in 'apps' is
3743 the same as the ID listed in 'app-ids'. The check will also check that
3744 there are no duplicate IDs issued. Note that an app ID should be
3745 a globaly unique numerical identifier for app/app-like features. Once
3746 an ID is registered, the ID is never freed up so that if an app is
3747 reinstalled it will have the same ID.
3748
3749 Returns: main.TRUE if the check passes and
3750 main.FALSE if the check fails or
3751 main.ERROR if there is some error in processing the test
3752 """
3753 try:
Jon Hall390696c2015-05-05 17:13:41 -07003754 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003755 rawJson = self.appIDs( jsonFormat=True )
3756 if rawJson:
3757 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003758 else:
Jon Hallc6793552016-01-19 14:18:37 -08003759 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003760 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003761 rawJson = self.apps( jsonFormat=True )
3762 if rawJson:
3763 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003764 else:
Jon Hallc6793552016-01-19 14:18:37 -08003765 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003766 bail = True
3767 if bail:
3768 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003769 result = main.TRUE
3770 for app in apps:
3771 appID = app.get( 'id' )
3772 if appID is None:
3773 main.log.error( "Error parsing app: " + str( app ) )
3774 result = main.FALSE
3775 appName = app.get( 'name' )
3776 if appName is None:
3777 main.log.error( "Error parsing app: " + str( app ) )
3778 result = main.FALSE
3779 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003780 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003781 # main.log.debug( "Comparing " + str( app ) + " to " +
3782 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003783 if not current: # if ids doesn't have this id
3784 result = main.FALSE
3785 main.log.error( "'app-ids' does not have the ID for " +
3786 str( appName ) + " that apps does." )
3787 elif len( current ) > 1:
3788 # there is more than one app with this ID
3789 result = main.FALSE
3790 # We will log this later in the method
3791 elif not current[0][ 'name' ] == appName:
3792 currentName = current[0][ 'name' ]
3793 result = main.FALSE
3794 main.log.error( "'app-ids' has " + str( currentName ) +
3795 " registered under id:" + str( appID ) +
3796 " but 'apps' has " + str( appName ) )
3797 else:
3798 pass # id and name match!
3799 # now make sure that app-ids has no duplicates
3800 idsList = []
3801 namesList = []
3802 for item in ids:
3803 idsList.append( item[ 'id' ] )
3804 namesList.append( item[ 'name' ] )
3805 if len( idsList ) != len( set( idsList ) ) or\
3806 len( namesList ) != len( set( namesList ) ):
3807 main.log.error( "'app-ids' has some duplicate entries: \n"
3808 + json.dumps( ids,
3809 sort_keys=True,
3810 indent=4,
3811 separators=( ',', ': ' ) ) )
3812 result = main.FALSE
3813 return result
Jon Hallc6793552016-01-19 14:18:37 -08003814 except ( TypeError, ValueError ):
3815 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003816 return main.ERROR
3817 except pexpect.EOF:
3818 main.log.error( self.name + ": EOF exception found" )
3819 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003820 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003821 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003822 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003823 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003824
Jon Hallfb760a02015-04-13 15:35:03 -07003825 def getCfg( self, component=None, propName=None, short=False,
3826 jsonFormat=True ):
3827 """
3828 Get configuration settings from onos cli
3829 Optional arguments:
3830 component - Optionally only list configurations for a specific
3831 component. If None, all components with configurations
3832 are displayed. Case Sensitive string.
3833 propName - If component is specified, propName option will show
3834 only this specific configuration from that component.
3835 Case Sensitive string.
3836 jsonFormat - Returns output as json. Note that this will override
3837 the short option
3838 short - Short, less verbose, version of configurations.
3839 This is overridden by the json option
3840 returns:
3841 Output from cli as a string or None on error
3842 """
3843 try:
3844 baseStr = "cfg"
3845 cmdStr = " get"
3846 componentStr = ""
3847 if component:
3848 componentStr += " " + component
3849 if propName:
3850 componentStr += " " + propName
3851 if jsonFormat:
3852 baseStr += " -j"
3853 elif short:
3854 baseStr += " -s"
3855 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003856 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003857 assert "Command not found:" not in output, output
3858 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003859 return output
3860 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003861 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003862 return None
3863 except TypeError:
3864 main.log.exception( self.name + ": Object not as expected" )
3865 return None
3866 except pexpect.EOF:
3867 main.log.error( self.name + ": EOF exception found" )
3868 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003869 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003870 except Exception:
3871 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003872 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003873
3874 def setCfg( self, component, propName, value=None, check=True ):
3875 """
3876 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003877 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003878 component - The case sensitive name of the component whose
3879 property is to be set
3880 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003881 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003882 value - The value to set the property to. If None, will unset the
3883 property and revert it to it's default value(if applicable)
3884 check - Boolean, Check whether the option was successfully set this
3885 only applies when a value is given.
3886 returns:
3887 main.TRUE on success or main.FALSE on failure. If check is False,
3888 will return main.TRUE unless there is an error
3889 """
3890 try:
3891 baseStr = "cfg"
3892 cmdStr = " set " + str( component ) + " " + str( propName )
3893 if value is not None:
3894 cmdStr += " " + str( value )
3895 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003896 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003897 assert "Command not found:" not in output, output
3898 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003899 if value and check:
3900 results = self.getCfg( component=str( component ),
3901 propName=str( propName ),
3902 jsonFormat=True )
3903 # Check if current value is what we just set
3904 try:
3905 jsonOutput = json.loads( results )
3906 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003907 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003908 main.log.exception( "Error parsing cfg output" )
3909 main.log.error( "output:" + repr( results ) )
3910 return main.FALSE
3911 if current == str( value ):
3912 return main.TRUE
3913 return main.FALSE
3914 return main.TRUE
3915 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003916 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003917 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003918 except ( TypeError, ValueError ):
3919 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003920 return main.FALSE
3921 except pexpect.EOF:
3922 main.log.error( self.name + ": EOF exception found" )
3923 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003924 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003925 except Exception:
3926 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003927 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003928
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003929 def distPrimitivesSend( self, cmd ):
3930 """
3931 Function to handle sending cli commands for the distributed primitives test app
3932
3933 This command will catch some exceptions and retry the command on some
3934 specific store exceptions.
3935
3936 Required arguments:
3937 cmd - The command to send to the cli
3938 returns:
3939 string containing the cli output
3940 None on Error
3941 """
3942 try:
3943 output = self.sendline( cmd )
3944 try:
3945 assert output is not None, "Error in sendline"
3946 # TODO: Maybe make this less hardcoded
3947 # ConsistentMap Exceptions
3948 assert "org.onosproject.store.service" not in output
3949 # Node not leader
3950 assert "java.lang.IllegalStateException" not in output
3951 except AssertionError:
3952 main.log.error( "Error in processing '" + cmd + "' " +
3953 "command: " + str( output ) )
3954 retryTime = 30 # Conservative time, given by Madan
3955 main.log.info( "Waiting " + str( retryTime ) +
3956 "seconds before retrying." )
3957 time.sleep( retryTime ) # Due to change in mastership
3958 output = self.sendline( cmd )
3959 assert output is not None, "Error in sendline"
3960 assert "Command not found:" not in output, output
3961 assert "Error executing command" not in output, output
3962 main.log.info( self.name + ": " + output )
3963 return output
3964 except AssertionError:
3965 main.log.exception( "Error in processing '" + cmd + "' command." )
3966 return None
3967 except TypeError:
3968 main.log.exception( self.name + ": Object not as expected" )
3969 return None
3970 except pexpect.EOF:
3971 main.log.error( self.name + ": EOF exception found" )
3972 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003973 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003974 except Exception:
3975 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003976 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003977
Jon Hall390696c2015-05-05 17:13:41 -07003978 def setTestAdd( self, setName, values ):
3979 """
3980 CLI command to add elements to a distributed set.
3981 Arguments:
3982 setName - The name of the set to add to.
3983 values - The value(s) to add to the set, space seperated.
3984 Example usages:
3985 setTestAdd( "set1", "a b c" )
3986 setTestAdd( "set2", "1" )
3987 returns:
3988 main.TRUE on success OR
3989 main.FALSE if elements were already in the set OR
3990 main.ERROR on error
3991 """
3992 try:
3993 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003994 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003995 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3996 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jon Hall390696c2015-05-05 17:13:41 -07003997 if re.search( positiveMatch, output):
3998 return main.TRUE
3999 elif re.search( negativeMatch, output):
4000 return main.FALSE
4001 else:
4002 main.log.error( self.name + ": setTestAdd did not" +
4003 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004004 main.log.debug( self.name + " actual: " + repr( output ) )
4005 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004006 except TypeError:
4007 main.log.exception( self.name + ": Object not as expected" )
4008 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004009 except Exception:
4010 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004011 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004012
4013 def setTestRemove( self, setName, values, clear=False, retain=False ):
4014 """
4015 CLI command to remove elements from a distributed set.
4016 Required arguments:
4017 setName - The name of the set to remove from.
4018 values - The value(s) to remove from the set, space seperated.
4019 Optional arguments:
4020 clear - Clear all elements from the set
4021 retain - Retain only the given values. (intersection of the
4022 original set and the given set)
4023 returns:
4024 main.TRUE on success OR
4025 main.FALSE if the set was not changed OR
4026 main.ERROR on error
4027 """
4028 try:
4029 cmdStr = "set-test-remove "
4030 if clear:
4031 cmdStr += "-c " + str( setName )
4032 elif retain:
4033 cmdStr += "-r " + str( setName ) + " " + str( values )
4034 else:
4035 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004036 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004037 if clear:
4038 pattern = "Set " + str( setName ) + " cleared"
4039 if re.search( pattern, output ):
4040 return main.TRUE
4041 elif retain:
4042 positivePattern = str( setName ) + " was pruned to contain " +\
4043 "only elements of set \[(.*)\]"
4044 negativePattern = str( setName ) + " was not changed by " +\
4045 "retaining only elements of the set " +\
4046 "\[(.*)\]"
4047 if re.search( positivePattern, output ):
4048 return main.TRUE
4049 elif re.search( negativePattern, output ):
4050 return main.FALSE
4051 else:
4052 positivePattern = "\[(.*)\] was removed from the set " +\
4053 str( setName )
4054 if ( len( values.split() ) == 1 ):
4055 negativePattern = "\[(.*)\] was not in set " +\
4056 str( setName )
4057 else:
4058 negativePattern = "No element of \[(.*)\] was in set " +\
4059 str( setName )
4060 if re.search( positivePattern, output ):
4061 return main.TRUE
4062 elif re.search( negativePattern, output ):
4063 return main.FALSE
4064 main.log.error( self.name + ": setTestRemove did not" +
4065 " match expected output" )
4066 main.log.debug( self.name + " expected: " + pattern )
4067 main.log.debug( self.name + " actual: " + repr( output ) )
4068 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004069 except TypeError:
4070 main.log.exception( self.name + ": Object not as expected" )
4071 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004072 except Exception:
4073 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004074 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004075
4076 def setTestGet( self, setName, values="" ):
4077 """
4078 CLI command to get the elements in a distributed set.
4079 Required arguments:
4080 setName - The name of the set to remove from.
4081 Optional arguments:
4082 values - The value(s) to check if in the set, space seperated.
4083 returns:
4084 main.ERROR on error OR
4085 A list of elements in the set if no optional arguments are
4086 supplied OR
4087 A tuple containing the list then:
4088 main.FALSE if the given values are not in the set OR
4089 main.TRUE if the given values are in the set OR
4090 """
4091 try:
4092 values = str( values ).strip()
4093 setName = str( setName ).strip()
4094 length = len( values.split() )
4095 containsCheck = None
4096 # Patterns to match
4097 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004098 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004099 containsTrue = "Set " + setName + " contains the value " + values
4100 containsFalse = "Set " + setName + " did not contain the value " +\
4101 values
4102 containsAllTrue = "Set " + setName + " contains the the subset " +\
4103 setPattern
4104 containsAllFalse = "Set " + setName + " did not contain the the" +\
4105 " subset " + setPattern
4106
4107 cmdStr = "set-test-get "
4108 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004109 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004110 if length == 0:
4111 match = re.search( pattern, output )
4112 else: # if given values
4113 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004114 patternTrue = pattern + "\r\n" + containsTrue
4115 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004116 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004117 patternTrue = pattern + "\r\n" + containsAllTrue
4118 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004119 matchTrue = re.search( patternTrue, output )
4120 matchFalse = re.search( patternFalse, output )
4121 if matchTrue:
4122 containsCheck = main.TRUE
4123 match = matchTrue
4124 elif matchFalse:
4125 containsCheck = main.FALSE
4126 match = matchFalse
4127 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004128 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004129 "expected output" )
4130 main.log.debug( self.name + " expected: " + pattern )
4131 main.log.debug( self.name + " actual: " + repr( output ) )
4132 match = None
4133 if match:
4134 setMatch = match.group( 1 )
4135 if setMatch == '':
4136 setList = []
4137 else:
4138 setList = setMatch.split( ", " )
4139 if length > 0:
4140 return ( setList, containsCheck )
4141 else:
4142 return setList
4143 else: # no match
4144 main.log.error( self.name + ": setTestGet did not" +
4145 " match expected output" )
4146 main.log.debug( self.name + " expected: " + pattern )
4147 main.log.debug( self.name + " actual: " + repr( output ) )
4148 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004149 except TypeError:
4150 main.log.exception( self.name + ": Object not as expected" )
4151 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004152 except Exception:
4153 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004154 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004155
4156 def setTestSize( self, setName ):
4157 """
4158 CLI command to get the elements in a distributed set.
4159 Required arguments:
4160 setName - The name of the set to remove from.
4161 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004162 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004163 None on error
4164 """
4165 try:
4166 # TODO: Should this check against the number of elements returned
4167 # and then return true/false based on that?
4168 setName = str( setName ).strip()
4169 # Patterns to match
4170 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004171 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004172 setPattern
4173 cmdStr = "set-test-get -s "
4174 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004175 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004176 match = re.search( pattern, output )
4177 if match:
4178 setSize = int( match.group( 1 ) )
4179 setMatch = match.group( 2 )
4180 if len( setMatch.split() ) == setSize:
4181 main.log.info( "The size returned by " + self.name +
4182 " matches the number of elements in " +
4183 "the returned set" )
4184 else:
4185 main.log.error( "The size returned by " + self.name +
4186 " does not match the number of " +
4187 "elements in the returned set." )
4188 return setSize
4189 else: # no match
4190 main.log.error( self.name + ": setTestGet did not" +
4191 " match expected output" )
4192 main.log.debug( self.name + " expected: " + pattern )
4193 main.log.debug( self.name + " actual: " + repr( output ) )
4194 return None
Jon Hall390696c2015-05-05 17:13:41 -07004195 except TypeError:
4196 main.log.exception( self.name + ": Object not as expected" )
4197 return None
Jon Hall390696c2015-05-05 17:13:41 -07004198 except Exception:
4199 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004200 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004201
Jon Hall80daded2015-05-27 16:07:00 -07004202 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004203 """
4204 Command to list the various counters in the system.
4205 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004206 if jsonFormat, a string of the json object returned by the cli
4207 command
4208 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004209 None on error
4210 """
Jon Hall390696c2015-05-05 17:13:41 -07004211 try:
Jon Hall390696c2015-05-05 17:13:41 -07004212 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004213 if jsonFormat:
4214 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004215 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004216 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004217 assert "Command not found:" not in output, output
4218 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004219 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004220 return output
Jon Hall390696c2015-05-05 17:13:41 -07004221 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004222 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004223 return None
Jon Hall390696c2015-05-05 17:13:41 -07004224 except TypeError:
4225 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004226 return None
Jon Hall390696c2015-05-05 17:13:41 -07004227 except pexpect.EOF:
4228 main.log.error( self.name + ": EOF exception found" )
4229 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004230 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004231 except Exception:
4232 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004233 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004234
Jon Hall935db192016-04-19 00:22:04 -07004235 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004236 """
Jon Halle1a3b752015-07-22 13:02:46 -07004237 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004238 Required arguments:
4239 counter - The name of the counter to increment.
4240 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004241 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004242 returns:
4243 integer value of the counter or
4244 None on Error
4245 """
4246 try:
4247 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004248 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004249 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004250 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004251 if delta != 1:
4252 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004253 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004254 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004255 match = re.search( pattern, output )
4256 if match:
4257 return int( match.group( 1 ) )
4258 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004259 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004260 " match expected output." )
4261 main.log.debug( self.name + " expected: " + pattern )
4262 main.log.debug( self.name + " actual: " + repr( output ) )
4263 return None
Jon Hall390696c2015-05-05 17:13:41 -07004264 except TypeError:
4265 main.log.exception( self.name + ": Object not as expected" )
4266 return None
Jon Hall390696c2015-05-05 17:13:41 -07004267 except Exception:
4268 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004269 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004270
Jon Hall935db192016-04-19 00:22:04 -07004271 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004272 """
4273 CLI command to get a distributed counter then add a delta to it.
4274 Required arguments:
4275 counter - The name of the counter to increment.
4276 Optional arguments:
4277 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004278 returns:
4279 integer value of the counter or
4280 None on Error
4281 """
4282 try:
4283 counter = str( counter )
4284 delta = int( delta )
4285 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004286 cmdStr += counter
4287 if delta != 1:
4288 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004289 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004290 pattern = counter + " was updated to (-?\d+)"
4291 match = re.search( pattern, output )
4292 if match:
4293 return int( match.group( 1 ) )
4294 else:
4295 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4296 " match expected output." )
4297 main.log.debug( self.name + " expected: " + pattern )
4298 main.log.debug( self.name + " actual: " + repr( output ) )
4299 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004300 except TypeError:
4301 main.log.exception( self.name + ": Object not as expected" )
4302 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004303 except Exception:
4304 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004305 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004306
4307 def valueTestGet( self, valueName ):
4308 """
4309 CLI command to get the value of an atomic value.
4310 Required arguments:
4311 valueName - The name of the value to get.
4312 returns:
4313 string value of the value or
4314 None on Error
4315 """
4316 try:
4317 valueName = str( valueName )
4318 cmdStr = "value-test "
4319 operation = "get"
4320 cmdStr = "value-test {} {}".format( valueName,
4321 operation )
4322 output = self.distPrimitivesSend( cmdStr )
4323 pattern = "(\w+)"
4324 match = re.search( pattern, output )
4325 if match:
4326 return match.group( 1 )
4327 else:
4328 main.log.error( self.name + ": valueTestGet did not" +
4329 " match expected output." )
4330 main.log.debug( self.name + " expected: " + pattern )
4331 main.log.debug( self.name + " actual: " + repr( output ) )
4332 return None
4333 except TypeError:
4334 main.log.exception( self.name + ": Object not as expected" )
4335 return None
4336 except Exception:
4337 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004338 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004339
4340 def valueTestSet( self, valueName, newValue ):
4341 """
4342 CLI command to set the value of an atomic value.
4343 Required arguments:
4344 valueName - The name of the value to set.
4345 newValue - The value to assign to the given value.
4346 returns:
4347 main.TRUE on success or
4348 main.ERROR on Error
4349 """
4350 try:
4351 valueName = str( valueName )
4352 newValue = str( newValue )
4353 operation = "set"
4354 cmdStr = "value-test {} {} {}".format( valueName,
4355 operation,
4356 newValue )
4357 output = self.distPrimitivesSend( cmdStr )
4358 if output is not None:
4359 return main.TRUE
4360 else:
4361 return main.ERROR
4362 except TypeError:
4363 main.log.exception( self.name + ": Object not as expected" )
4364 return main.ERROR
4365 except Exception:
4366 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004367 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004368
4369 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4370 """
4371 CLI command to compareAndSet the value of an atomic value.
4372 Required arguments:
4373 valueName - The name of the value.
4374 oldValue - Compare the current value of the atomic value to this
4375 newValue - If the value equals oldValue, set the value to newValue
4376 returns:
4377 main.TRUE on success or
4378 main.FALSE on failure or
4379 main.ERROR on Error
4380 """
4381 try:
4382 valueName = str( valueName )
4383 oldValue = str( oldValue )
4384 newValue = str( newValue )
4385 operation = "compareAndSet"
4386 cmdStr = "value-test {} {} {} {}".format( valueName,
4387 operation,
4388 oldValue,
4389 newValue )
4390 output = self.distPrimitivesSend( cmdStr )
4391 pattern = "(\w+)"
4392 match = re.search( pattern, output )
4393 if match:
4394 result = match.group( 1 )
4395 if result == "true":
4396 return main.TRUE
4397 elif result == "false":
4398 return main.FALSE
4399 else:
4400 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4401 " match expected output." )
4402 main.log.debug( self.name + " expected: " + pattern )
4403 main.log.debug( self.name + " actual: " + repr( output ) )
4404 return main.ERROR
4405 except TypeError:
4406 main.log.exception( self.name + ": Object not as expected" )
4407 return main.ERROR
4408 except Exception:
4409 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004410 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004411
4412 def valueTestGetAndSet( self, valueName, newValue ):
4413 """
4414 CLI command to getAndSet the value of an atomic value.
4415 Required arguments:
4416 valueName - The name of the value to get.
4417 newValue - The value to assign to the given value
4418 returns:
4419 string value of the value or
4420 None on Error
4421 """
4422 try:
4423 valueName = str( valueName )
4424 cmdStr = "value-test "
4425 operation = "getAndSet"
4426 cmdStr += valueName + " " + operation
4427 cmdStr = "value-test {} {} {}".format( valueName,
4428 operation,
4429 newValue )
4430 output = self.distPrimitivesSend( cmdStr )
4431 pattern = "(\w+)"
4432 match = re.search( pattern, output )
4433 if match:
4434 return match.group( 1 )
4435 else:
4436 main.log.error( self.name + ": valueTestGetAndSet did not" +
4437 " match expected output." )
4438 main.log.debug( self.name + " expected: " + pattern )
4439 main.log.debug( self.name + " actual: " + repr( output ) )
4440 return None
4441 except TypeError:
4442 main.log.exception( self.name + ": Object not as expected" )
4443 return None
4444 except Exception:
4445 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004446 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004447
4448 def valueTestDestroy( self, valueName ):
4449 """
4450 CLI command to destroy an atomic value.
4451 Required arguments:
4452 valueName - The name of the value to destroy.
4453 returns:
4454 main.TRUE on success or
4455 main.ERROR on Error
4456 """
4457 try:
4458 valueName = str( valueName )
4459 cmdStr = "value-test "
4460 operation = "destroy"
4461 cmdStr += valueName + " " + operation
4462 output = self.distPrimitivesSend( cmdStr )
4463 if output is not None:
4464 return main.TRUE
4465 else:
4466 return main.ERROR
4467 except TypeError:
4468 main.log.exception( self.name + ": Object not as expected" )
4469 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004470 except Exception:
4471 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004472 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004473
YPZhangfebf7302016-05-24 16:45:56 -07004474 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004475 """
4476 Description: Execute summary command in onos
4477 Returns: json object ( summary -j ), returns main.FALSE if there is
4478 no output
4479
4480 """
4481 try:
4482 cmdStr = "summary"
4483 if jsonFormat:
4484 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004485 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004486 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004487 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004488 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004489 if not handle:
4490 main.log.error( self.name + ": There is no output in " +
4491 "summary command" )
4492 return main.FALSE
4493 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004494 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004495 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004496 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004497 except TypeError:
4498 main.log.exception( self.name + ": Object not as expected" )
4499 return None
4500 except pexpect.EOF:
4501 main.log.error( self.name + ": EOF exception found" )
4502 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004503 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004504 except Exception:
4505 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004506 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004507
Jon Hall935db192016-04-19 00:22:04 -07004508 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004509 """
4510 CLI command to get the value of a key in a consistent map using
4511 transactions. This a test function and can only get keys from the
4512 test map hard coded into the cli command
4513 Required arguments:
4514 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004515 returns:
4516 The string value of the key or
4517 None on Error
4518 """
4519 try:
4520 keyName = str( keyName )
4521 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004522 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004523 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004524 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4525 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004526 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004527 return None
4528 else:
4529 match = re.search( pattern, output )
4530 if match:
4531 return match.groupdict()[ 'value' ]
4532 else:
4533 main.log.error( self.name + ": transactionlMapGet did not" +
4534 " match expected output." )
4535 main.log.debug( self.name + " expected: " + pattern )
4536 main.log.debug( self.name + " actual: " + repr( output ) )
4537 return None
4538 except TypeError:
4539 main.log.exception( self.name + ": Object not as expected" )
4540 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004541 except Exception:
4542 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004543 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004544
Jon Hall935db192016-04-19 00:22:04 -07004545 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004546 """
4547 CLI command to put a value into 'numKeys' number of keys in a
4548 consistent map using transactions. This a test function and can only
4549 put into keys named 'Key#' of the test map hard coded into the cli command
4550 Required arguments:
4551 numKeys - Number of keys to add the value to
4552 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004553 returns:
4554 A dictionary whose keys are the name of the keys put into the map
4555 and the values of the keys are dictionaries whose key-values are
4556 'value': value put into map and optionaly
4557 'oldValue': Previous value in the key or
4558 None on Error
4559
4560 Example output
4561 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4562 'Key2': {'value': 'Testing'} }
4563 """
4564 try:
4565 numKeys = str( numKeys )
4566 value = str( value )
4567 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004568 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004569 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004570 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4571 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4572 results = {}
4573 for line in output.splitlines():
4574 new = re.search( newPattern, line )
4575 updated = re.search( updatedPattern, line )
4576 if new:
4577 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4578 elif updated:
4579 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004580 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004581 else:
4582 main.log.error( self.name + ": transactionlMapGet did not" +
4583 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004584 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4585 newPattern,
4586 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004587 main.log.debug( self.name + " actual: " + repr( output ) )
4588 return results
4589 except TypeError:
4590 main.log.exception( self.name + ": Object not as expected" )
4591 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004592 except Exception:
4593 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004594 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004595
acsmarsdaea66c2015-09-03 11:44:06 -07004596 def maps( self, jsonFormat=True ):
4597 """
4598 Description: Returns result of onos:maps
4599 Optional:
4600 * jsonFormat: enable json formatting of output
4601 """
4602 try:
4603 cmdStr = "maps"
4604 if jsonFormat:
4605 cmdStr += " -j"
4606 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004607 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004608 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004609 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004610 except AssertionError:
4611 main.log.exception( "" )
4612 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004613 except TypeError:
4614 main.log.exception( self.name + ": Object not as expected" )
4615 return None
4616 except pexpect.EOF:
4617 main.log.error( self.name + ": EOF exception found" )
4618 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004619 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004620 except Exception:
4621 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004622 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004623
4624 def getSwController( self, uri, jsonFormat=True ):
4625 """
4626 Descrition: Gets the controller information from the device
4627 """
4628 try:
4629 cmd = "device-controllers "
4630 if jsonFormat:
4631 cmd += "-j "
4632 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004633 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004634 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004635 return response
Jon Hallc6793552016-01-19 14:18:37 -08004636 except AssertionError:
4637 main.log.exception( "" )
4638 return None
GlennRC050596c2015-11-18 17:06:41 -08004639 except TypeError:
4640 main.log.exception( self.name + ": Object not as expected" )
4641 return None
4642 except pexpect.EOF:
4643 main.log.error( self.name + ": EOF exception found" )
4644 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004645 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004646 except Exception:
4647 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004648 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004649
4650 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4651 """
4652 Descrition: sets the controller(s) for the specified device
4653
4654 Parameters:
4655 Required: uri - String: The uri of the device(switch).
4656 ip - String or List: The ip address of the controller.
4657 This parameter can be formed in a couple of different ways.
4658 VALID:
4659 10.0.0.1 - just the ip address
4660 tcp:10.0.0.1 - the protocol and the ip address
4661 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4662 so that you can add controllers with different
4663 protocols and ports
4664 INVALID:
4665 10.0.0.1:6653 - this is not supported by ONOS
4666
4667 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4668 port - The port number.
4669 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4670
4671 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4672 """
4673 try:
4674 cmd = "device-setcontrollers"
4675
4676 if jsonFormat:
4677 cmd += " -j"
4678 cmd += " " + uri
4679 if isinstance( ip, str ):
4680 ip = [ip]
4681 for item in ip:
4682 if ":" in item:
4683 sitem = item.split( ":" )
4684 if len(sitem) == 3:
4685 cmd += " " + item
4686 elif "." in sitem[1]:
4687 cmd += " {}:{}".format(item, port)
4688 else:
4689 main.log.error( "Malformed entry: " + item )
4690 raise TypeError
4691 else:
4692 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004693 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004694 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004695 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004696 if "Error" in response:
4697 main.log.error( response )
4698 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004699 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004700 except AssertionError:
4701 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004702 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004703 except TypeError:
4704 main.log.exception( self.name + ": Object not as expected" )
4705 return main.FALSE
4706 except pexpect.EOF:
4707 main.log.error( self.name + ": EOF exception found" )
4708 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004709 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004710 except Exception:
4711 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004712 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004713
4714 def removeDevice( self, device ):
4715 '''
4716 Description:
4717 Remove a device from ONOS by passing the uri of the device(s).
4718 Parameters:
4719 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4720 Returns:
4721 Returns main.FALSE if an exception is thrown or an error is present
4722 in the response. Otherwise, returns main.TRUE.
4723 NOTE:
4724 If a host cannot be removed, then this function will return main.FALSE
4725 '''
4726 try:
4727 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004728 deviceStr = device
4729 device = []
4730 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004731
4732 for d in device:
4733 time.sleep( 1 )
4734 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004735 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004736 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004737 if "Error" in response:
4738 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4739 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004740 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004741 except AssertionError:
4742 main.log.exception( "" )
4743 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004744 except TypeError:
4745 main.log.exception( self.name + ": Object not as expected" )
4746 return main.FALSE
4747 except pexpect.EOF:
4748 main.log.error( self.name + ": EOF exception found" )
4749 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004750 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004751 except Exception:
4752 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004753 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004754
4755 def removeHost( self, host ):
4756 '''
4757 Description:
4758 Remove a host from ONOS by passing the id of the host(s)
4759 Parameters:
4760 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4761 Returns:
4762 Returns main.FALSE if an exception is thrown or an error is present
4763 in the response. Otherwise, returns main.TRUE.
4764 NOTE:
4765 If a host cannot be removed, then this function will return main.FALSE
4766 '''
4767 try:
4768 if type( host ) is str:
4769 host = list( host )
4770
4771 for h in host:
4772 time.sleep( 1 )
4773 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004774 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004775 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004776 if "Error" in response:
4777 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4778 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004779 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004780 except AssertionError:
4781 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004782 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004783 except TypeError:
4784 main.log.exception( self.name + ": Object not as expected" )
4785 return main.FALSE
4786 except pexpect.EOF:
4787 main.log.error( self.name + ": EOF exception found" )
4788 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004789 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004790 except Exception:
4791 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004792 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004793
YPZhangfebf7302016-05-24 16:45:56 -07004794 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004795 '''
4796 Description:
4797 Bring link down or up in the null-provider.
4798 params:
4799 begin - (string) One end of a device or switch.
4800 end - (string) the other end of the device or switch
4801 returns:
4802 main.TRUE if no exceptions were thrown and no Errors are
4803 present in the resoponse. Otherwise, returns main.FALSE
4804 '''
4805 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004806 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004807 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004808 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004809 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004810 if "Error" in response or "Failure" in response:
4811 main.log.error( response )
4812 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004813 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004814 except AssertionError:
4815 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004816 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004817 except TypeError:
4818 main.log.exception( self.name + ": Object not as expected" )
4819 return main.FALSE
4820 except pexpect.EOF:
4821 main.log.error( self.name + ": EOF exception found" )
4822 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004823 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004824 except Exception:
4825 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004826 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004827
Jon Hall2c8959e2016-12-16 12:17:34 -08004828 def portstate( self, dpid, port, state ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07004829 '''
4830 Description:
4831 Changes the state of port in an OF switch by means of the
4832 PORTSTATUS OF messages.
4833 params:
Jon Hall2c8959e2016-12-16 12:17:34 -08004834 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
4835 port - (string) target port in the device. Ex: '2'
4836 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07004837 returns:
4838 main.TRUE if no exceptions were thrown and no Errors are
4839 present in the resoponse. Otherwise, returns main.FALSE
4840 '''
4841 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08004842 state = state.lower()
4843 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07004844 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004845 response = self.sendline( cmd, showResponse=True )
4846 assert response is not None, "Error in sendline"
4847 assert "Command not found:" not in response, response
4848 if "Error" in response or "Failure" in response:
4849 main.log.error( response )
4850 return main.FALSE
4851 return main.TRUE
4852 except AssertionError:
4853 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004854 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07004855 except TypeError:
4856 main.log.exception( self.name + ": Object not as expected" )
4857 return main.FALSE
4858 except pexpect.EOF:
4859 main.log.error( self.name + ": EOF exception found" )
4860 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004861 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004862 except Exception:
4863 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004864 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004865
4866 def logSet( self, level="INFO", app="org.onosproject" ):
4867 """
4868 Set the logging level to lvl for a specific app
4869 returns main.TRUE on success
4870 returns main.FALSE if Error occurred
4871 if noExit is True, TestON will not exit, but clean up
4872 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4873 Level defaults to INFO
4874 """
4875 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004876 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004877 self.handle.expect( "onos>" )
4878
4879 response = self.handle.before
4880 if re.search( "Error", response ):
4881 return main.FALSE
4882 return main.TRUE
4883 except pexpect.TIMEOUT:
4884 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07004885 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004886 except pexpect.EOF:
4887 main.log.error( self.name + ": EOF exception found" )
4888 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004889 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004890 except Exception:
4891 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004892 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004893
4894 def getGraphDict( self, timeout=60, includeHost=False ):
4895 """
4896 Return a dictionary which describes the latest network topology data as a
4897 graph.
4898 An example of the dictionary:
4899 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4900 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4901 Each vertex should at least have an 'edges' attribute which describes the
4902 adjacency information. The value of 'edges' attribute is also represented by
4903 a dictionary, which maps each edge (identified by the neighbor vertex) to a
4904 list of attributes.
4905 An example of the edges dictionary:
4906 'edges': { vertex2: { 'port': ..., 'weight': ... },
4907 vertex3: { 'port': ..., 'weight': ... } }
4908 If includeHost == True, all hosts (and host-switch links) will be included
4909 in topology data.
4910 """
4911 graphDict = {}
4912 try:
4913 links = self.links()
4914 links = json.loads( links )
4915 devices = self.devices()
4916 devices = json.loads( devices )
4917 idToDevice = {}
4918 for device in devices:
4919 idToDevice[ device[ 'id' ] ] = device
4920 if includeHost:
4921 hosts = self.hosts()
4922 # FIXME: support 'includeHost' argument
4923 for link in links:
4924 nodeA = link[ 'src' ][ 'device' ]
4925 nodeB = link[ 'dst' ][ 'device' ]
4926 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07004927 if nodeA not in graphDict.keys():
4928 graphDict[ nodeA ] = { 'edges': {},
4929 'dpid': idToDevice[ nodeA ][ 'id' ][3:],
4930 'type': idToDevice[ nodeA ][ 'type' ],
4931 'available': idToDevice[ nodeA ][ 'available' ],
4932 'role': idToDevice[ nodeA ][ 'role' ],
4933 'mfr': idToDevice[ nodeA ][ 'mfr' ],
4934 'hw': idToDevice[ nodeA ][ 'hw' ],
4935 'sw': idToDevice[ nodeA ][ 'sw' ],
4936 'serial': idToDevice[ nodeA ][ 'serial' ],
4937 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
4938 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07004939 else:
4940 # Assert nodeB is not connected to any current links of nodeA
4941 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07004942 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
4943 'type': link[ 'type' ],
4944 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07004945 return graphDict
4946 except ( TypeError, ValueError ):
4947 main.log.exception( self.name + ": Object not as expected" )
4948 return None
4949 except KeyError:
4950 main.log.exception( self.name + ": KeyError exception found" )
4951 return None
4952 except AssertionError:
4953 main.log.exception( self.name + ": AssertionError exception found" )
4954 return None
4955 except pexpect.EOF:
4956 main.log.error( self.name + ": EOF exception found" )
4957 main.log.error( self.name + ": " + self.handle.before )
4958 return None
4959 except Exception:
4960 main.log.exception( self.name + ": Uncaught exception!" )
4961 return None
YPZhangcbc2a062016-07-11 10:55:44 -07004962
4963 def getIntentPerfSummary( self ):
4964 '''
4965 Send command to check intent-perf summary
4966 Returns: dictionary for intent-perf summary
4967 if something wrong, function will return None
4968 '''
4969 cmd = "intent-perf -s"
4970 respDic = {}
4971 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08004972 assert resp is not None, "Error in sendline"
4973 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07004974 try:
4975 # Generate the dictionary to return
4976 for l in resp.split( "\n" ):
4977 # Delete any white space in line
4978 temp = re.sub( r'\s+', '', l )
4979 temp = temp.split( ":" )
4980 respDic[ temp[0] ] = temp[ 1 ]
4981
4982 except (TypeError, ValueError):
4983 main.log.exception( self.name + ": Object not as expected" )
4984 return None
4985 except KeyError:
4986 main.log.exception( self.name + ": KeyError exception found" )
4987 return None
4988 except AssertionError:
4989 main.log.exception( self.name + ": AssertionError exception found" )
4990 return None
4991 except pexpect.EOF:
4992 main.log.error( self.name + ": EOF exception found" )
4993 main.log.error( self.name + ": " + self.handle.before )
4994 return None
4995 except Exception:
4996 main.log.exception( self.name + ": Uncaught exception!" )
4997 return None
4998 return respDic
4999
Chiyu Chengec63bde2016-11-17 18:11:36 -08005000 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005001 """
5002 Searches the latest ONOS log file for the given search term and
5003 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005004
chengchiyu08303a02016-09-08 17:40:26 -07005005 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005006 searchTerm:
5007 The string to grep from the ONOS log.
5008 startLine:
5009 The term that decides which line is the start to search the searchTerm in
5010 the karaf log. For now, startTerm only works in 'first' mode.
5011 logNum:
5012 In some extreme cases, one karaf log is not big enough to contain all the
5013 information.Because of this, search mutiply logs is necessary to capture
5014 the right result. logNum is the number of karaf logs that we need to search
5015 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005016 mode:
5017 all: return all the strings that contain the search term
5018 last: return the last string that contains the search term
5019 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005020 num: return the number of times that the searchTerm appears in the log
5021 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005022 """
5023 try:
5024 assert type( searchTerm ) is str
Jon Halle0f0b342017-04-18 11:43:47 -07005025 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005026 logPath = '/opt/onos/log/karaf.log.'
5027 logPaths = '/opt/onos/log/karaf.log'
5028 for i in range( 1, logNum ):
5029 logPaths = logPath + str( i ) + " " + logPaths
5030 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005031 if startLine:
5032 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5033 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005034 if mode == 'all':
5035 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005036 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005037 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005038 elif mode == 'first':
5039 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5040 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005041 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005042 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005043 return num
You Wang6d301d42017-04-21 10:49:33 -07005044 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005045 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
5046 return int(totalLines)
You Wang6d301d42017-04-21 10:49:33 -07005047 else:
5048 main.log.error( self.name + " unsupported mode" )
5049 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005050 before = self.sendline( cmd )
5051 before = before.splitlines()
5052 # make sure the returned list only contains the search term
5053 returnLines = [line for line in before if searchTerm in line]
5054 return returnLines
5055 except AssertionError:
5056 main.log.error( self.name + " searchTerm is not string type" )
5057 return None
5058 except pexpect.EOF:
5059 main.log.error( self.name + ": EOF exception found" )
5060 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005061 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005062 except pexpect.TIMEOUT:
5063 main.log.error( self.name + ": TIMEOUT exception found" )
5064 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005065 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005066 except Exception:
5067 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005068 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005069
5070 def vplsShow( self, jsonFormat=True ):
5071 """
5072 Description: Returns result of onos:vpls show, which should list the
5073 configured VPLS networks and the assigned interfaces.
5074 Optional:
5075 * jsonFormat: enable json formatting of output
5076 Returns:
5077 The output of the command or None on error.
5078 """
5079 try:
5080 cmdStr = "vpls show"
5081 if jsonFormat:
5082 raise NotImplementedError
5083 cmdStr += " -j"
5084 handle = self.sendline( cmdStr )
5085 assert handle is not None, "Error in sendline"
5086 assert "Command not found:" not in handle, handle
5087 return handle
5088 except AssertionError:
5089 main.log.exception( "" )
5090 return None
5091 except TypeError:
5092 main.log.exception( self.name + ": Object not as expected" )
5093 return None
5094 except pexpect.EOF:
5095 main.log.error( self.name + ": EOF exception found" )
5096 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005097 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005098 except NotImplementedError:
5099 main.log.exception( self.name + ": Json output not supported")
5100 return None
5101 except Exception:
5102 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005103 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005104
5105 def parseVplsShow( self ):
5106 """
5107 Parse the cli output of 'vpls show' into json output. This is required
5108 as there is currently no json output available.
5109 """
5110 try:
5111 output = []
5112 raw = self.vplsShow( jsonFormat=False )
5113 namePat = "VPLS name: (?P<name>\w+)"
5114 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5115 encapPat = "Encapsulation: (?P<encap>\w+)"
5116 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5117 mIter = re.finditer( pattern, raw )
5118 for match in mIter:
5119 item = {}
5120 item[ 'name' ] = match.group( 'name' )
5121 ifaces = match.group( 'interfaces' ).split( ', ')
5122 if ifaces == [ "" ]:
5123 ifaces = []
5124 item[ 'interfaces' ] = ifaces
5125 encap = match.group( 'encap' )
5126 if encap != 'NONE':
5127 item[ 'encapsulation' ] = encap.lower()
5128 output.append( item )
5129 return output
5130 except Exception:
5131 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005132 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005133
5134 def vplsList( self, jsonFormat=True ):
5135 """
5136 Description: Returns result of onos:vpls list, which should list the
5137 configured VPLS networks.
5138 Optional:
5139 * jsonFormat: enable json formatting of output
5140 """
5141 try:
5142 cmdStr = "vpls list"
5143 if jsonFormat:
5144 raise NotImplementedError
5145 cmdStr += " -j"
5146 handle = self.sendline( cmdStr )
5147 assert handle is not None, "Error in sendline"
5148 assert "Command not found:" not in handle, handle
5149 return handle
5150 except AssertionError:
5151 main.log.exception( "" )
5152 return None
5153 except TypeError:
5154 main.log.exception( self.name + ": Object not as expected" )
5155 return None
5156 except pexpect.EOF:
5157 main.log.error( self.name + ": EOF exception found" )
5158 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005159 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005160 except NotImplementedError:
5161 main.log.exception( self.name + ": Json output not supported")
5162 return None
5163 except Exception:
5164 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005165 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005166
5167 def vplsCreate( self, network ):
5168 """
5169 CLI command to create a new VPLS network.
5170 Required arguments:
5171 network - String name of the network to create.
5172 returns:
5173 main.TRUE on success and main.FALSE on failure
5174 """
5175 try:
5176 network = str( network )
5177 cmdStr = "vpls create "
5178 cmdStr += network
5179 output = self.sendline( cmdStr )
5180 assert output is not None, "Error in sendline"
5181 assert "Command not found:" not in output, output
5182 assert "Error executing command" not in output, output
5183 assert "VPLS already exists:" not in output, output
5184 return main.TRUE
5185 except AssertionError:
5186 main.log.exception( "" )
5187 return main.FALSE
5188 except TypeError:
5189 main.log.exception( self.name + ": Object not as expected" )
5190 return main.FALSE
5191 except pexpect.EOF:
5192 main.log.error( self.name + ": EOF exception found" )
5193 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005194 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005195 except Exception:
5196 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005197 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005198
5199 def vplsDelete( self, network ):
5200 """
5201 CLI command to delete a VPLS network.
5202 Required arguments:
5203 network - Name of the network to delete.
5204 returns:
5205 main.TRUE on success and main.FALSE on failure
5206 """
5207 try:
5208 network = str( network )
5209 cmdStr = "vpls delete "
5210 cmdStr += network
5211 output = self.sendline( cmdStr )
5212 assert output is not None, "Error in sendline"
5213 assert "Command not found:" not in output, output
5214 assert "Error executing command" not in output, output
5215 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005216 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005217 return main.TRUE
5218 except AssertionError:
5219 main.log.exception( "" )
5220 return main.FALSE
5221 except TypeError:
5222 main.log.exception( self.name + ": Object not as expected" )
5223 return main.FALSE
5224 except pexpect.EOF:
5225 main.log.error( self.name + ": EOF exception found" )
5226 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005227 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005228 except Exception:
5229 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005230 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005231
5232 def vplsAddIface( self, network, iface ):
5233 """
5234 CLI command to add an interface to a VPLS network.
5235 Required arguments:
5236 network - Name of the network to add the interface to.
5237 iface - The ONOS name for an interface.
5238 returns:
5239 main.TRUE on success and main.FALSE on failure
5240 """
5241 try:
5242 network = str( network )
5243 iface = str( iface )
5244 cmdStr = "vpls add-if "
5245 cmdStr += network + " " + iface
5246 output = self.sendline( cmdStr )
5247 assert output is not None, "Error in sendline"
5248 assert "Command not found:" not in output, output
5249 assert "Error executing command" not in output, output
5250 assert "already associated to network" not in output, output
5251 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005252 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005253 return main.TRUE
5254 except AssertionError:
5255 main.log.exception( "" )
5256 return main.FALSE
5257 except TypeError:
5258 main.log.exception( self.name + ": Object not as expected" )
5259 return main.FALSE
5260 except pexpect.EOF:
5261 main.log.error( self.name + ": EOF exception found" )
5262 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005263 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005264 except Exception:
5265 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005266 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005267
5268 def vplsRemIface( self, network, iface ):
5269 """
5270 CLI command to remove an interface from a VPLS network.
5271 Required arguments:
5272 network - Name of the network to remove the interface from.
5273 iface - Name of the interface to remove.
5274 returns:
5275 main.TRUE on success and main.FALSE on failure
5276 """
5277 try:
5278 iface = str( iface )
5279 cmdStr = "vpls rem-if "
5280 cmdStr += network + " " + iface
5281 output = self.sendline( cmdStr )
5282 assert output is not None, "Error in sendline"
5283 assert "Command not found:" not in output, output
5284 assert "Error executing command" not in output, output
5285 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005286 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005287 return main.TRUE
5288 except AssertionError:
5289 main.log.exception( "" )
5290 return main.FALSE
5291 except TypeError:
5292 main.log.exception( self.name + ": Object not as expected" )
5293 return main.FALSE
5294 except pexpect.EOF:
5295 main.log.error( self.name + ": EOF exception found" )
5296 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005297 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005298 except Exception:
5299 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005300 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005301
5302 def vplsClean( self ):
5303 """
5304 Description: Clears the VPLS app configuration.
5305 Returns: main.TRUE on success and main.FALSE on failure
5306 """
5307 try:
5308 cmdStr = "vpls clean"
5309 handle = self.sendline( cmdStr )
5310 assert handle is not None, "Error in sendline"
5311 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005312 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005313 return handle
5314 except AssertionError:
5315 main.log.exception( "" )
5316 return main.FALSE
5317 except TypeError:
5318 main.log.exception( self.name + ": Object not as expected" )
5319 return main.FALSE
5320 except pexpect.EOF:
5321 main.log.error( self.name + ": EOF exception found" )
5322 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005323 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005324 except Exception:
5325 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005326 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005327
5328 def vplsSetEncap( self, network, encapType ):
5329 """
5330 CLI command to add an interface to a VPLS network.
5331 Required arguments:
5332 network - Name of the network to create.
5333 encapType - Type of encapsulation.
5334 returns:
5335 main.TRUE on success and main.FALSE on failure
5336 """
5337 try:
5338 network = str( network )
5339 encapType = str( encapType ).upper()
5340 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5341 cmdStr = "vpls set-encap "
5342 cmdStr += network + " " + encapType
5343 output = self.sendline( cmdStr )
5344 assert output is not None, "Error in sendline"
5345 assert "Command not found:" not in output, output
5346 assert "Error executing command" not in output, output
5347 assert "already associated to network" not in output, output
5348 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005349 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005350 return main.TRUE
5351 except AssertionError:
5352 main.log.exception( "" )
5353 return main.FALSE
5354 except TypeError:
5355 main.log.exception( self.name + ": Object not as expected" )
5356 return main.FALSE
5357 except pexpect.EOF:
5358 main.log.error( self.name + ": EOF exception found" )
5359 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005360 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005361 except Exception:
5362 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005363 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005364
5365 def interfaces( self, jsonFormat=True ):
5366 """
5367 Description: Returns result of interfaces command.
5368 Optional:
5369 * jsonFormat: enable json formatting of output
5370 Returns:
5371 The output of the command or None on error.
5372 """
5373 try:
5374 cmdStr = "interfaces"
5375 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005376 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005377 cmdStr += " -j"
5378 handle = self.sendline( cmdStr )
5379 assert handle is not None, "Error in sendline"
5380 assert "Command not found:" not in handle, handle
5381 return handle
5382 except AssertionError:
5383 main.log.exception( "" )
5384 return None
5385 except TypeError:
5386 main.log.exception( self.name + ": Object not as expected" )
5387 return None
5388 except pexpect.EOF:
5389 main.log.error( self.name + ": EOF exception found" )
5390 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005391 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005392 except NotImplementedError:
5393 main.log.exception( self.name + ": Json output not supported")
5394 return None
5395 except Exception:
5396 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005397 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005398
5399 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
5400 '''
5401 Get the timestamp of searchTerm from karaf log.
5402
5403 Arguments:
5404 splitTerm_before and splitTerm_after:
5405
5406 The terms that split the string that contains the timeStamp of
5407 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5408 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5409 and the splitTerm_after is "x"
5410
5411 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005412 Please look at the "logsearch" Function in onosclidriver.py
Chiyu Chengec63bde2016-11-17 18:11:36 -08005413 '''
5414 if logNum < 0:
5415 main.log.error("Get wrong log number ")
5416 return main.ERROR
5417 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
5418 if len(lines) == 0:
5419 main.log.warn( "Captured timestamp string is empty" )
5420 return main.ERROR
5421 lines = lines[ 0 ]
5422 try:
5423 assert type(lines) is str
5424 # get the target value
5425 line = lines.split( splitTerm_before )
5426 key = line[ 1 ].split( splitTerm_after )
5427 return int( key[ 0 ] )
5428 except IndexError:
5429 main.log.warn( "Index Error!" )
5430 return main.ERROR
5431 except AssertionError:
5432 main.log.warn( "Search Term Not Found " )
5433 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005434
5435 def workQueueAdd( self, queueName, value ):
5436 """
5437 CLI command to add a string to the specified Work Queue.
5438 This function uses the distributed primitives test app, which
5439 gives some cli access to distributed primitives for testing
5440 purposes only.
5441
5442 Required arguments:
5443 queueName - The name of the queue to add to
5444 value - The value to add to the queue
5445 returns:
5446 main.TRUE on success, main.FALSE on failure and
5447 main.ERROR on error.
5448 """
5449 try:
5450 queueName = str( queueName )
5451 value = str( value )
5452 prefix = "work-queue-test"
5453 operation = "add"
5454 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5455 output = self.distPrimitivesSend( cmdStr )
5456 if "Invalid operation name" in output:
5457 main.log.warn( output )
5458 return main.ERROR
5459 elif "Done" in output:
5460 return main.TRUE
5461 except TypeError:
5462 main.log.exception( self.name + ": Object not as expected" )
5463 return main.ERROR
5464 except Exception:
5465 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005466 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005467
5468 def workQueueAddMultiple( self, queueName, value1, value2 ):
5469 """
5470 CLI command to add two strings to the specified Work Queue.
5471 This function uses the distributed primitives test app, which
5472 gives some cli access to distributed primitives for testing
5473 purposes only.
5474
5475 Required arguments:
5476 queueName - The name of the queue to add to
5477 value1 - The first value to add to the queue
5478 value2 - The second value to add to the queue
5479 returns:
5480 main.TRUE on success, main.FALSE on failure and
5481 main.ERROR on error.
5482 """
5483 try:
5484 queueName = str( queueName )
5485 value1 = str( value1 )
5486 value2 = str( value2 )
5487 prefix = "work-queue-test"
5488 operation = "addMultiple"
5489 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5490 output = self.distPrimitivesSend( cmdStr )
5491 if "Invalid operation name" in output:
5492 main.log.warn( output )
5493 return main.ERROR
5494 elif "Done" in output:
5495 return main.TRUE
5496 except TypeError:
5497 main.log.exception( self.name + ": Object not as expected" )
5498 return main.ERROR
5499 except Exception:
5500 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005501 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005502
5503 def workQueueTakeAndComplete( self, queueName, number=1 ):
5504 """
5505 CLI command to take a value from the specified Work Queue and compelte it.
5506 This function uses the distributed primitives test app, which
5507 gives some cli access to distributed primitives for testing
5508 purposes only.
5509
5510 Required arguments:
5511 queueName - The name of the queue to add to
5512 number - The number of items to take and complete
5513 returns:
5514 main.TRUE on success, main.FALSE on failure and
5515 main.ERROR on error.
5516 """
5517 try:
5518 queueName = str( queueName )
5519 number = str( int( number ) )
5520 prefix = "work-queue-test"
5521 operation = "takeAndComplete"
5522 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5523 output = self.distPrimitivesSend( cmdStr )
5524 if "Invalid operation name" in output:
5525 main.log.warn( output )
5526 return main.ERROR
5527 elif "Done" in output:
5528 return main.TRUE
5529 except TypeError:
5530 main.log.exception( self.name + ": Object not as expected" )
5531 return main.ERROR
5532 except Exception:
5533 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005534 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005535
5536 def workQueueDestroy( self, queueName ):
5537 """
5538 CLI command to destroy the specified Work Queue.
5539 This function uses the distributed primitives test app, which
5540 gives some cli access to distributed primitives for testing
5541 purposes only.
5542
5543 Required arguments:
5544 queueName - The name of the queue to add to
5545 returns:
5546 main.TRUE on success, main.FALSE on failure and
5547 main.ERROR on error.
5548 """
5549 try:
5550 queueName = str( queueName )
5551 prefix = "work-queue-test"
5552 operation = "destroy"
5553 cmdStr = " ".join( [ prefix, queueName, operation ] )
5554 output = self.distPrimitivesSend( cmdStr )
5555 if "Invalid operation name" in output:
5556 main.log.warn( output )
5557 return main.ERROR
5558 return main.TRUE
5559 except TypeError:
5560 main.log.exception( self.name + ": Object not as expected" )
5561 return main.ERROR
5562 except Exception:
5563 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005564 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005565
5566 def workQueueTotalPending( self, queueName ):
5567 """
5568 CLI command to get the Total Pending items of the specified Work Queue.
5569 This function uses the distributed primitives test app, which
5570 gives some cli access to distributed primitives for testing
5571 purposes only.
5572
5573 Required arguments:
5574 queueName - The name of the queue to add to
5575 returns:
5576 The number of Pending items in the specified work queue or
5577 None on error
5578 """
5579 try:
5580 queueName = str( queueName )
5581 prefix = "work-queue-test"
5582 operation = "totalPending"
5583 cmdStr = " ".join( [ prefix, queueName, operation ] )
5584 output = self.distPrimitivesSend( cmdStr )
5585 pattern = r'\d+'
5586 if "Invalid operation name" in output:
5587 main.log.warn( output )
5588 return None
5589 else:
5590 match = re.search( pattern, output )
5591 return match.group(0)
5592 except ( AttributeError, TypeError ):
5593 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5594 return None
5595 except Exception:
5596 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005597 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005598
5599 def workQueueTotalCompleted( self, queueName ):
5600 """
5601 CLI command to get the Total Completed items of the specified Work Queue.
5602 This function uses the distributed primitives test app, which
5603 gives some cli access to distributed primitives for testing
5604 purposes only.
5605
5606 Required arguments:
5607 queueName - The name of the queue to add to
5608 returns:
5609 The number of complete items in the specified work queue or
5610 None on error
5611 """
5612 try:
5613 queueName = str( queueName )
5614 prefix = "work-queue-test"
5615 operation = "totalCompleted"
5616 cmdStr = " ".join( [ prefix, queueName, operation ] )
5617 output = self.distPrimitivesSend( cmdStr )
5618 pattern = r'\d+'
5619 if "Invalid operation name" in output:
5620 main.log.warn( output )
5621 return None
5622 else:
5623 match = re.search( pattern, output )
5624 return match.group(0)
5625 except ( AttributeError, TypeError ):
5626 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5627 return None
5628 except Exception:
5629 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005630 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005631
5632 def workQueueTotalInProgress( self, queueName ):
5633 """
5634 CLI command to get the Total In Progress items of the specified Work Queue.
5635 This function uses the distributed primitives test app, which
5636 gives some cli access to distributed primitives for testing
5637 purposes only.
5638
5639 Required arguments:
5640 queueName - The name of the queue to add to
5641 returns:
5642 The number of In Progress items in the specified work queue or
5643 None on error
5644 """
5645 try:
5646 queueName = str( queueName )
5647 prefix = "work-queue-test"
5648 operation = "totalInProgress"
5649 cmdStr = " ".join( [ prefix, queueName, operation ] )
5650 output = self.distPrimitivesSend( cmdStr )
5651 pattern = r'\d+'
5652 if "Invalid operation name" in output:
5653 main.log.warn( output )
5654 return None
5655 else:
5656 match = re.search( pattern, output )
5657 return match.group(0)
5658 except ( AttributeError, TypeError ):
5659 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5660 return None
5661 except Exception:
5662 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005663 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005664
5665 def events( self, args='-a' ):
5666 """
5667 Description: Returns events -a command output
5668 Optional:
5669 add other arguments
5670 """
5671 try:
5672 cmdStr = "events"
5673 if args:
5674 cmdStr += " " + args
5675 handle = self.sendline( cmdStr )
5676 assert handle is not None, "Error in sendline"
5677 assert "Command not found:" not in handle, handle
5678 return handle
5679 except AssertionError:
5680 main.log.exception( "" )
5681 return None
5682 except TypeError:
5683 main.log.exception( self.name + ": Object not as expected" )
5684 return None
5685 except pexpect.EOF:
5686 main.log.error( self.name + ": EOF exception found" )
5687 main.log.error( self.name + ": " + self.handle.before )
5688 main.cleanAndExit()
5689 except Exception:
5690 main.log.exception( self.name + ": Uncaught exception!" )
5691 main.cleanAndExit()
5692
5693 def getMaster( self, deviceID ):
5694 """
5695 Description: Obtains current master using "roles" command for a specific deviceID
5696 """
5697 try:
5698 return str( self.getRole( deviceID )[ 'master' ] )
5699 except AssertionError:
5700 main.log.exception( "" )
5701 return None
5702 except TypeError:
5703 main.log.exception( self.name + ": Object not as expected" )
5704 return None
5705 except pexpect.EOF:
5706 main.log.error( self.name + ": EOF exception found" )
5707 main.log.error( self.name + ": " + self.handle.before )
5708 main.cleanAndExit()
5709 except Exception:
5710 main.log.exception( self.name + ": Uncaught exception!" )
5711 main.cleanAndExit()