blob: 52ef98a5c1e76dab628903da5bf2ba5af689c6da [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07004OCT 13 2014
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005Copyright 2014 Open Networking Foundation (ONF)
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07006
7Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
8the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
9or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
10
11 TestON is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 2 of the License, or
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000014 (at your option) any later version.
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070015
16 TestON is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with TestON. If not, see <http://www.gnu.org/licenses/>.
23"""
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000024
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070025"""
andrewonlab95ce8322014-10-13 14:12:04 -040026This driver enters the onos> prompt to issue commands.
27
kelvin8ec71442015-01-15 16:57:00 -080028Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -040029functions and document properly.
30
31If you are a contributor to the driver, please
32list your email here for future contact:
33
34jhall@onlab.us
35andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040036shreya@onlab.us
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +000037jeremyr@opennetworking.org
kelvin8ec71442015-01-15 16:57:00 -080038"""
andrewonlab95ce8322014-10-13 14:12:04 -040039import pexpect
40import re
Jon Hall30b82fa2015-03-04 17:15:43 -080041import json
42import types
Jon Hallbd16b922015-03-26 17:53:15 -070043import time
kelvin-onlaba4074292015-07-09 15:19:49 -070044import os
andrewonlab95ce8322014-10-13 14:12:04 -040045from drivers.common.clidriver import CLI
You Wangdb8cd0a2016-05-26 15:19:45 -070046from core.graph import Graph
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -070047from cStringIO import StringIO
48from itertools import izip
andrewonlab95ce8322014-10-13 14:12:04 -040049
kelvin8ec71442015-01-15 16:57:00 -080050class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040051
kelvin8ec71442015-01-15 16:57:00 -080052 def __init__( self ):
53 """
54 Initialize client
55 """
Jon Hallefbd9792015-03-05 16:11:36 -080056 self.name = None
57 self.home = None
58 self.handle = None
Devin Limdc78e202017-06-09 18:30:07 -070059 self.karafUser = None
60 self.karafPass = None
You Wangdb8cd0a2016-05-26 15:19:45 -070061 self.graph = Graph()
Devin Limdc78e202017-06-09 18:30:07 -070062 super( OnosCliDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080063
Jeremy Ronquillo82705492017-10-18 14:19:55 -070064 def checkOptions( self, var, defaultVar ):
Devin Limdc78e202017-06-09 18:30:07 -070065 if var is None or var == "":
66 return defaultVar
67 return var
Jeremy Ronquillo82705492017-10-18 14:19:55 -070068
kelvin8ec71442015-01-15 16:57:00 -080069 def connect( self, **connectargs ):
70 """
andrewonlab95ce8322014-10-13 14:12:04 -040071 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080072 """
andrewonlab95ce8322014-10-13 14:12:04 -040073 try:
74 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080075 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070076 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040077 for key in self.options:
78 if key == "home":
Devin Limdc78e202017-06-09 18:30:07 -070079 self.home = self.options[ key ]
80 elif key == "karaf_username":
81 self.karafUser = self.options[ key ]
82 elif key == "karaf_password":
83 self.karafPass = self.options[ key ]
84
Jeremy Ronquillo82705492017-10-18 14:19:55 -070085 self.home = self.checkOptions( self.home, "~/onos" )
86 self.karafUser = self.checkOptions( self.karafUser, self.user_name )
87 self.karafPass = self.checkOptions( self.karafPass, self.pwd )
andrewonlab95ce8322014-10-13 14:12:04 -040088
kelvin-onlaba4074292015-07-09 15:19:49 -070089 for key in self.options:
90 if key == 'onosIp':
91 self.onosIp = self.options[ 'onosIp' ]
92 break
93
kelvin8ec71442015-01-15 16:57:00 -080094 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070095
96 try:
Jon Hallc6793552016-01-19 14:18:37 -080097 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070098 self.ip_address = os.getenv( str( self.ip_address ) )
99 else:
100 main.log.info( self.name +
101 ": Trying to connect to " +
102 self.ip_address )
103
104 except KeyError:
105 main.log.info( "Invalid host name," +
106 " connecting to local host instead" )
107 self.ip_address = 'localhost'
108 except Exception as inst:
109 main.log.error( "Uncaught exception: " + str( inst ) )
110
kelvin8ec71442015-01-15 16:57:00 -0800111 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800112 user_name=self.user_name,
113 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800114 port=self.port,
115 pwd=self.pwd,
116 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400117
kelvin8ec71442015-01-15 16:57:00 -0800118 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700119 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400120 if self.handle:
121 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800122 else:
123 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400124 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800125 except TypeError:
126 main.log.exception( self.name + ": Object not as expected" )
127 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400128 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800129 main.log.error( self.name + ": EOF exception found" )
130 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700131 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800132 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800133 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700134 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400135
kelvin8ec71442015-01-15 16:57:00 -0800136 def disconnect( self ):
137 """
andrewonlab95ce8322014-10-13 14:12:04 -0400138 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800139 """
Jon Halld61331b2015-02-17 16:35:47 -0800140 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400141 try:
Jon Hall61282e32015-03-19 11:34:11 -0700142 if self.handle:
143 i = self.logout()
144 if i == main.TRUE:
145 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700146 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700147 self.handle.sendline( "exit" )
148 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800149 except TypeError:
150 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800151 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400152 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800153 main.log.error( self.name + ": EOF exception found" )
154 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700155 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700156 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700157 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800158 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800159 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400160 response = main.FALSE
161 return response
162
kelvin8ec71442015-01-15 16:57:00 -0800163 def logout( self ):
164 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500165 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700166 Returns main.TRUE if exited CLI and
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000167 main.FALSE on timeout (not guranteed you are disconnected)
Jon Hall61282e32015-03-19 11:34:11 -0700168 None on TypeError
169 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800170 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500171 try:
Jon Hall61282e32015-03-19 11:34:11 -0700172 if self.handle:
173 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700174 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ],
Jon Hall61282e32015-03-19 11:34:11 -0700175 timeout=10 )
176 if i == 0: # In ONOS CLI
177 self.handle.sendline( "logout" )
Devin Limdc78e202017-06-09 18:30:07 -0700178 j = self.handle.expect( [ self.prompt,
Jon Hallbfe00002016-04-05 10:23:54 -0700179 "Command not found:",
180 pexpect.TIMEOUT ] )
181 if j == 0: # Successfully logged out
182 return main.TRUE
183 elif j == 1 or j == 2:
184 # ONOS didn't fully load, and logout command isn't working
185 # or the command timed out
186 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700187 try:
Devin Limdc78e202017-06-09 18:30:07 -0700188 self.handle.expect( self.prompt )
Jon Hall64ab3bd2016-05-13 11:29:44 -0700189 except pexpect.TIMEOUT:
190 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700191 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700192 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700193 main.log.warn( "Unknown repsonse to logout command: '{}'",
194 repr( self.handle.before ) )
195 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700196 elif i == 1: # not in CLI
197 return main.TRUE
198 elif i == 3: # Timeout
199 return main.FALSE
200 else:
andrewonlab9627f432014-11-14 12:45:10 -0500201 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800202 except TypeError:
203 main.log.exception( self.name + ": Object not as expected" )
204 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500205 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800206 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700207 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700208 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700209 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700210 main.log.error( self.name +
211 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800212 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800213 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700214 main.cleanAndExit()
andrewonlab38d2b4a2014-11-13 16:28:47 -0500215
kelvin-onlabd3b64892015-01-20 13:26:24 -0800216 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800217 """
andrewonlab95ce8322014-10-13 14:12:04 -0400218 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800219
andrewonlab95ce8322014-10-13 14:12:04 -0400220 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800221 """
andrewonlab95ce8322014-10-13 14:12:04 -0400222 try:
223 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800224 main.log.error( "Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700225 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400226 else:
kelvin8ec71442015-01-15 16:57:00 -0800227 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800229 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400230 # and that this driver will have to change accordingly
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700231 self.handle.expect( str( cellname ) )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800232 handleBefore = self.handle.before
233 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800234 # Get the rest of the handle
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700235 self.handle.sendline( "" )
236 self.handle.expect( self.prompt )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800237 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400238
kelvin-onlabd3b64892015-01-20 13:26:24 -0800239 main.log.info( "Cell call returned: " + handleBefore +
240 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400241
242 return main.TRUE
243
Jon Halld4d4b372015-01-28 16:02:41 -0800244 except TypeError:
245 main.log.exception( self.name + ": Object not as expected" )
246 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400247 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800248 main.log.error( self.name + ": eof exception found" )
249 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700250 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800251 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800252 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700253 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -0800254
pingping-lin57a56ce2015-05-20 16:43:48 -0700255 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800256 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800257 """
Jon Hallefbd9792015-03-05 16:11:36 -0800258 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800259 by user would be used to set the current karaf shell idle timeout.
260 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800261 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800262 Below is an example to start a session with 60 seconds idle timeout
263 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800264
Hari Krishna25d42f72015-01-05 15:08:28 -0800265 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800266 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800267
kelvin-onlabd3b64892015-01-20 13:26:24 -0800268 Note: karafTimeout is left as str so that this could be read
269 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800270 """
You Wangf69ab392016-01-26 16:34:38 -0800271 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400272 try:
Jon Hall67253832016-12-05 09:47:13 -0800273 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800274 self.handle.sendline( "" )
275 x = self.handle.expect( [
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700276 self.prompt, "onos>" ], commandlineTimeout )
andrewonlab48829f62014-11-17 13:49:01 -0500277 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800278 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500279 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400280
Jon Hall67253832016-12-05 09:47:13 -0800281 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800282 if waitForStart:
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800283 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
284 startCliCommand = "onos-wait-for-start "
Chiyu Chengef109502016-11-21 15:51:38 -0800285 else:
286 startCliCommand = "onos "
287 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800288 i = self.handle.expect( [
289 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700290 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400291
292 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800293 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800294 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800295 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800296 "config:property-set -p org.apache.karaf.shell\
297 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800298 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700299 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800300 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800301 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400302 return main.TRUE
303 else:
kelvin8ec71442015-01-15 16:57:00 -0800304 # If failed, send ctrl+c to process and try again
305 main.log.info( "Starting CLI failed. Retrying..." )
306 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800307 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800308 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
309 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400310 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800311 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800312 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800313 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800314 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800315 "config:property-set -p org.apache.karaf.shell\
316 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800317 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700318 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800319 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800320 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400321 return main.TRUE
322 else:
kelvin8ec71442015-01-15 16:57:00 -0800323 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800324 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400325 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400326
Jon Halld4d4b372015-01-28 16:02:41 -0800327 except TypeError:
328 main.log.exception( self.name + ": Object not as expected" )
329 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400330 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800331 main.log.error( self.name + ": EOF exception found" )
332 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700333 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800334 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800335 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700336 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400337
suibin zhang116647a2016-05-06 16:30:09 -0700338 def startCellCli( self, karafTimeout="",
339 commandlineTimeout=10, onosStartTimeout=60 ):
340 """
341 Start CLI on onos ecll handle.
342
343 karafTimeout is an optional argument. karafTimeout value passed
344 by user would be used to set the current karaf shell idle timeout.
345 Note that when ever this property is modified the shell will exit and
346 the subsequent login would reflect new idle timeout.
347 Below is an example to start a session with 60 seconds idle timeout
348 ( input value is in milliseconds ):
349
350 tValue = "60000"
351
352 Note: karafTimeout is left as str so that this could be read
353 and passed to startOnosCli from PARAMS file as str.
354 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000355
suibin zhang116647a2016-05-06 16:30:09 -0700356 try:
357 self.handle.sendline( "" )
358 x = self.handle.expect( [
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700359 self.prompt, "onos>" ], commandlineTimeout )
suibin zhang116647a2016-05-06 16:30:09 -0700360
361 if x == 1:
362 main.log.info( "ONOS cli is already running" )
363 return main.TRUE
364
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800365 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
suibin zhang116647a2016-05-06 16:30:09 -0700366 self.handle.sendline( "/opt/onos/bin/onos" )
367 i = self.handle.expect( [
368 "onos>",
369 pexpect.TIMEOUT ], onosStartTimeout )
370
371 if i == 0:
372 main.log.info( self.name + " CLI Started successfully" )
373 if karafTimeout:
374 self.handle.sendline(
375 "config:property-set -p org.apache.karaf.shell\
376 sshIdleTimeout " +
377 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700378 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700379 self.handle.sendline( "/opt/onos/bin/onos" )
380 self.handle.expect( "onos>" )
381 return main.TRUE
382 else:
383 # If failed, send ctrl+c to process and try again
384 main.log.info( "Starting CLI failed. Retrying..." )
385 self.handle.send( "\x03" )
386 self.handle.sendline( "/opt/onos/bin/onos" )
387 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
388 timeout=30 )
389 if i == 0:
390 main.log.info( self.name + " CLI Started " +
391 "successfully after retry attempt" )
392 if karafTimeout:
393 self.handle.sendline(
394 "config:property-set -p org.apache.karaf.shell\
395 sshIdleTimeout " +
396 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700397 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700398 self.handle.sendline( "/opt/onos/bin/onos" )
399 self.handle.expect( "onos>" )
400 return main.TRUE
401 else:
402 main.log.error( "Connection to CLI " +
403 self.name + " timeout" )
404 return main.FALSE
405
406 except TypeError:
407 main.log.exception( self.name + ": Object not as expected" )
408 return None
409 except pexpect.EOF:
410 main.log.error( self.name + ": EOF exception found" )
411 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700412 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700413 except Exception:
414 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700415 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700416
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800417 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800418 """
419 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800420 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800421 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700422 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800423 Available level: DEBUG, TRACE, INFO, WARN, ERROR
424 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800425 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800426 """
427 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800428 lvlStr = ""
429 if level:
430 lvlStr = "--level=" + level
431
kelvin-onlab338f5512015-02-06 10:53:16 -0800432 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700433 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800434 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800435
kelvin-onlab9f541032015-02-04 16:19:53 -0800436 response = self.handle.before
437 if re.search( "Error", response ):
438 return main.FALSE
439 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700440 except pexpect.TIMEOUT:
441 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700442 if noExit:
443 main.cleanup()
444 return None
445 else:
Devin Lim44075962017-08-11 10:56:37 -0700446 main.cleanAndExit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800447 except pexpect.EOF:
448 main.log.error( self.name + ": EOF exception found" )
449 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700450 if noExit:
451 main.cleanup()
452 return None
453 else:
Devin Lim44075962017-08-11 10:56:37 -0700454 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800455 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800456 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700457 if noExit:
458 main.cleanup()
459 return None
460 else:
Devin Lim44075962017-08-11 10:56:37 -0700461 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400462
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700463 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, dollarSign=False ):
kelvin8ec71442015-01-15 16:57:00 -0800464 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800465 Send a completely user specified string to
466 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400467 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800468
YPZhang14a4aa92016-07-15 13:37:15 -0700469 if noExit is True, TestON will not exit, and return None
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700470 if dollarSign is True, TestON will not expect for '$' as a new CLI or onos> prompt
471 since '$' can be in the output.
YPZhangebf9eb52016-05-12 15:20:24 -0700472
andrewonlaba18f6bf2014-10-13 19:31:54 -0400473 Warning: There are no sanity checking to commands
474 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800475
kelvin8ec71442015-01-15 16:57:00 -0800476 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400477 try:
Jon Halla495f562016-05-16 18:03:26 -0700478 # Try to reconnect if disconnected from cli
479 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700480 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ] )
Jon Halla495f562016-05-16 18:03:26 -0700481 if i == 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700482 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700483 if self.onosIp:
484 main.log.warn( "Trying to reconnect " + self.onosIp )
485 reconnectResult = self.startOnosCli( self.onosIp )
486 if reconnectResult:
487 main.log.info( self.name + ": onos cli session reconnected." )
488 else:
489 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700490 if noExit:
491 return None
492 else:
Devin Lim44075962017-08-11 10:56:37 -0700493 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700494 else:
Devin Lim44075962017-08-11 10:56:37 -0700495 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700496 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700497 main.log.warn( "Timeout when testing cli responsiveness" )
498 main.log.debug( self.handle.before )
499 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700500 self.handle.expect( "onos>" )
501
Jon Hall14a03b52016-05-11 12:07:30 -0700502 if debug:
503 # NOTE: This adds and average of .4 seconds per call
504 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700505 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 self.handle.sendline( cmdStr )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700507 if dollarSign:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700508 i = self.handle.expect( [ "onos>" ], timeout )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700509 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700510 i = self.handle.expect( [ "onos>", self.prompt ], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800511 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800512 # TODO: do something with i
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000513 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800514 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700515 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700516 main.log.debug( self.name + ": Raw output" )
517 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700518
519 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800520 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800521 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700522 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700523 main.log.debug( self.name + ": ansiEscape output" )
524 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700525
kelvin-onlabfb521662015-02-27 09:52:40 -0800526 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000527 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700528 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700529 main.log.debug( self.name + ": Removed extra returns " +
530 "from output" )
531 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700532
533 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800534 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700535 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700536 main.log.debug( self.name + ": parsed and stripped output" )
537 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700538
Jon Hall63604932015-02-26 17:09:50 -0800539 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700540 output = response.split( cmdStr.strip(), 1 )
541 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700542 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700543 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700544 main.log.debug( self.name + ": " + repr( r ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700545 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800546 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800547 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800548 return output
GlennRCed771242016-01-13 17:02:47 -0800549 except pexpect.TIMEOUT:
550 main.log.error( self.name + ":ONOS timeout" )
551 if debug:
552 main.log.debug( self.handle.before )
553 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700554 except IndexError:
555 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700556 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700557 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800558 except TypeError:
559 main.log.exception( self.name + ": Object not as expected" )
560 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400561 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800562 main.log.error( self.name + ": EOF exception found" )
563 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700564 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700565 return None
566 else:
Devin Lim44075962017-08-11 10:56:37 -0700567 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800568 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800569 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700570 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700571 return None
572 else:
Devin Lim44075962017-08-11 10:56:37 -0700573 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400574
kelvin8ec71442015-01-15 16:57:00 -0800575 # IMPORTANT NOTE:
576 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800577 # the cli command changing 'a:b' with 'aB'.
578 # Ex ) onos:topology > onosTopology
579 # onos:links > onosLinks
580 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800581
kelvin-onlabd3b64892015-01-20 13:26:24 -0800582 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800583 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400584 Adds a new cluster node by ID and address information.
585 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800586 * nodeId
587 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400588 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800589 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800590 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400591 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800592 cmdStr = "add-node " + str( nodeId ) + " " +\
593 str( ONOSIp ) + " " + str( tcpPort )
594 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700595 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800596 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800597 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800598 main.log.error( "Error in adding node" )
599 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800600 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400601 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400603 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800604 except AssertionError:
605 main.log.exception( "" )
606 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800607 except TypeError:
608 main.log.exception( self.name + ": Object not as expected" )
609 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400610 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800611 main.log.error( self.name + ": EOF exception found" )
612 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700613 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800614 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800615 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700616 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400617
kelvin-onlabd3b64892015-01-20 13:26:24 -0800618 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800619 """
andrewonlab86dc3082014-10-13 18:18:38 -0400620 Removes a cluster by ID
621 Issues command: 'remove-node [<node-id>]'
622 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800623 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800624 """
andrewonlab86dc3082014-10-13 18:18:38 -0400625 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400626
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700628 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700629 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800630 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700631 if re.search( "Error", handle ):
632 main.log.error( "Error in removing node" )
633 main.log.error( handle )
634 return main.FALSE
635 else:
636 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800637 except AssertionError:
638 main.log.exception( "" )
639 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800640 except TypeError:
641 main.log.exception( self.name + ": Object not as expected" )
642 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400643 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800644 main.log.error( self.name + ": EOF exception found" )
645 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700646 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800647 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800648 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700649 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400650
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700651 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800652 """
andrewonlab7c211572014-10-15 16:45:20 -0400653 List the nodes currently visible
654 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700655 Optional argument:
656 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800657 """
andrewonlab7c211572014-10-15 16:45:20 -0400658 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700659 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700660 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700661 cmdStr += " -j"
662 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700663 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800664 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700665 return output
Jon Hallc6793552016-01-19 14:18:37 -0800666 except AssertionError:
667 main.log.exception( "" )
668 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800669 except TypeError:
670 main.log.exception( self.name + ": Object not as expected" )
671 return None
andrewonlab7c211572014-10-15 16:45:20 -0400672 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800673 main.log.error( self.name + ": EOF exception found" )
674 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700675 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800676 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800677 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700678 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400679
kelvin8ec71442015-01-15 16:57:00 -0800680 def topology( self ):
681 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700682 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700683 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700684 Return:
685 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800686 """
andrewonlab95ce8322014-10-13 14:12:04 -0400687 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700688 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800690 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800691 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700692 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400693 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800694 except AssertionError:
695 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800696 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800697 except TypeError:
698 main.log.exception( self.name + ": Object not as expected" )
699 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400700 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800701 main.log.error( self.name + ": EOF exception found" )
702 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700703 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800704 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800705 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700706 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800707
jenkins7ead5a82015-03-13 10:28:21 -0700708 def deviceRemove( self, deviceId ):
709 """
710 Removes particular device from storage
711
712 TODO: refactor this function
713 """
714 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700715 cmdStr = "device-remove " + str( deviceId )
716 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800717 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800718 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700719 if re.search( "Error", handle ):
720 main.log.error( "Error in removing device" )
721 main.log.error( handle )
722 return main.FALSE
723 else:
724 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800725 except AssertionError:
726 main.log.exception( "" )
727 return None
jenkins7ead5a82015-03-13 10:28:21 -0700728 except TypeError:
729 main.log.exception( self.name + ": Object not as expected" )
730 return None
731 except pexpect.EOF:
732 main.log.error( self.name + ": EOF exception found" )
733 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700734 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700735 except Exception:
736 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700737 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700738
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800740 """
Jon Hall7b02d952014-10-17 20:14:54 -0400741 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400742 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800743 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800744 """
andrewonlab86dc3082014-10-13 18:18:38 -0400745 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700746 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700748 cmdStr += " -j"
749 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800750 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800751 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700752 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800753 except AssertionError:
754 main.log.exception( "" )
755 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800756 except TypeError:
757 main.log.exception( self.name + ": Object not as expected" )
758 return None
andrewonlab7c211572014-10-15 16:45:20 -0400759 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800760 main.log.error( self.name + ": EOF exception found" )
761 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700762 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800763 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800764 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700765 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400766
kelvin-onlabd3b64892015-01-20 13:26:24 -0800767 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800768 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800769 This balances the devices across all controllers
770 by issuing command: 'onos> onos:balance-masters'
771 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800772 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800773 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800774 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700775 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800776 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800777 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700778 if re.search( "Error", handle ):
779 main.log.error( "Error in balancing masters" )
780 main.log.error( handle )
781 return main.FALSE
782 else:
783 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800784 except AssertionError:
785 main.log.exception( "" )
786 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800787 except TypeError:
788 main.log.exception( self.name + ": Object not as expected" )
789 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800790 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800791 main.log.error( self.name + ": EOF exception found" )
792 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700793 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800794 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800795 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700796 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800797
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000798 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700799 """
800 Returns the output of the masters command.
801 Optional argument:
802 * jsonFormat - boolean indicating if you want output in json
803 """
804 try:
805 cmdStr = "onos:masters"
806 if jsonFormat:
807 cmdStr += " -j"
808 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700809 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800810 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700811 return output
Jon Hallc6793552016-01-19 14:18:37 -0800812 except AssertionError:
813 main.log.exception( "" )
814 return None
acsmars24950022015-07-30 18:00:43 -0700815 except TypeError:
816 main.log.exception( self.name + ": Object not as expected" )
817 return None
818 except pexpect.EOF:
819 main.log.error( self.name + ": EOF exception found" )
820 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700821 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700822 except Exception:
823 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700824 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700825
Jon Hallc6793552016-01-19 14:18:37 -0800826 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700827 """
828 Uses the master command to check that the devices' leadership
829 is evenly divided
830
831 Dependencies: checkMasters() and summary()
832
Jon Hall6509dbf2016-06-21 17:01:17 -0700833 Returns main.TRUE if the devices are balanced
834 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700835 Exits on Exception
836 Returns None on TypeError
837 """
838 try:
Jon Hallc6793552016-01-19 14:18:37 -0800839 summaryOutput = self.summary()
840 totalDevices = json.loads( summaryOutput )[ "devices" ]
841 except ( TypeError, ValueError ):
842 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
843 return None
844 try:
acsmars24950022015-07-30 18:00:43 -0700845 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800846 mastersOutput = self.checkMasters()
847 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700848 first = masters[ 0 ][ "size" ]
849 for master in masters:
850 totalOwnedDevices += master[ "size" ]
851 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
852 main.log.error( "Mastership not balanced" )
853 main.log.info( "\n" + self.checkMasters( False ) )
854 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700855 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700856 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700857 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800858 except ( TypeError, ValueError ):
859 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700860 return None
861 except pexpect.EOF:
862 main.log.error( self.name + ": EOF exception found" )
863 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700864 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700865 except Exception:
866 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700867 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700868
YPZhangfebf7302016-05-24 16:45:56 -0700869 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800870 """
Jon Halle8217482014-10-17 13:49:14 -0400871 Lists all core links
872 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800873 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800874 """
Jon Halle8217482014-10-17 13:49:14 -0400875 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700876 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800877 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700878 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700879 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800880 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800881 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700882 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800883 except AssertionError:
884 main.log.exception( "" )
885 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800886 except TypeError:
887 main.log.exception( self.name + ": Object not as expected" )
888 return None
Jon Halle8217482014-10-17 13:49:14 -0400889 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800890 main.log.error( self.name + ": EOF exception found" )
891 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700892 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800893 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800894 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700895 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400896
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800898 """
Jon Halle8217482014-10-17 13:49:14 -0400899 Lists all ports
900 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800901 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800902 """
Jon Halle8217482014-10-17 13:49:14 -0400903 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700904 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800905 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700906 cmdStr += " -j"
907 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800908 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800909 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700910 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800911 except AssertionError:
912 main.log.exception( "" )
913 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800914 except TypeError:
915 main.log.exception( self.name + ": Object not as expected" )
916 return None
Jon Halle8217482014-10-17 13:49:14 -0400917 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800918 main.log.error( self.name + ": EOF exception found" )
919 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700920 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800921 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800922 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700923 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400924
kelvin-onlabd3b64892015-01-20 13:26:24 -0800925 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800926 """
Jon Hall983a1702014-10-28 18:44:22 -0400927 Lists all devices and the controllers with roles assigned to them
928 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800929 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800930 """
andrewonlab7c211572014-10-15 16:45:20 -0400931 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700932 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800933 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700934 cmdStr += " -j"
935 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800936 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800937 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700938 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800939 except AssertionError:
940 main.log.exception( "" )
941 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800942 except TypeError:
943 main.log.exception( self.name + ": Object not as expected" )
944 return None
Jon Hall983a1702014-10-28 18:44:22 -0400945 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800946 main.log.error( self.name + ": EOF exception found" )
947 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700948 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800949 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800950 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700951 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -0400952
kelvin-onlabd3b64892015-01-20 13:26:24 -0800953 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800954 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800955 Given the a string containing the json representation of the "roles"
956 cli command and a partial or whole device id, returns a json object
957 containing the roles output for the first device whose id contains
958 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400959
960 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800961 A dict of the role assignments for the given device or
962 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800963 """
Jon Hall983a1702014-10-28 18:44:22 -0400964 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400966 return None
967 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800968 rawRoles = self.roles()
969 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800970 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800972 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800973 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400974 return device
975 return None
Jon Hallc6793552016-01-19 14:18:37 -0800976 except ( TypeError, ValueError ):
977 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800978 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400979 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800980 main.log.error( self.name + ": EOF exception found" )
981 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700982 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800983 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800984 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700985 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -0800986
kelvin-onlabd3b64892015-01-20 13:26:24 -0800987 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800988 """
Jon Hall94fd0472014-12-08 11:52:42 -0800989 Iterates through each device and checks if there is a master assigned
990 Returns: main.TRUE if each device has a master
991 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800992 """
Jon Hall94fd0472014-12-08 11:52:42 -0800993 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 rawRoles = self.roles()
995 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800996 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800997 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800998 # print device
999 if device[ 'master' ] == "none":
1000 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001001 return main.FALSE
1002 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001003 except ( TypeError, ValueError ):
1004 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001005 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001006 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001007 main.log.error( self.name + ": EOF exception found" )
1008 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001009 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001010 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001011 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001012 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001013
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001015 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001016 Returns string of paths, and the cost.
1017 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001018 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001019 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001020 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1021 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001022 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001023 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001024 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001025 main.log.error( "Error in getting paths" )
1026 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001027 else:
kelvin8ec71442015-01-15 16:57:00 -08001028 path = handle.split( ";" )[ 0 ]
1029 cost = handle.split( ";" )[ 1 ]
1030 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001031 except AssertionError:
1032 main.log.exception( "" )
1033 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001034 except TypeError:
1035 main.log.exception( self.name + ": Object not as expected" )
1036 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001037 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001038 main.log.error( self.name + ": EOF exception found" )
1039 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001040 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001041 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001042 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001043 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001044
kelvin-onlabd3b64892015-01-20 13:26:24 -08001045 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001046 """
Jon Hallffb386d2014-11-21 13:43:38 -08001047 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001048 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001049 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001050 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001051 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001052 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001054 cmdStr += " -j"
1055 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001056 if handle:
1057 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001058 # TODO: Maybe make this less hardcoded
1059 # ConsistentMap Exceptions
1060 assert "org.onosproject.store.service" not in handle
1061 # Node not leader
1062 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001063 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001064 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001065 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001066 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001067 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001068 except TypeError:
1069 main.log.exception( self.name + ": Object not as expected" )
1070 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001071 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001072 main.log.error( self.name + ": EOF exception found" )
1073 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001074 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001075 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001076 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001077 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001078
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001080 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001081 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001082
Jon Hallefbd9792015-03-05 16:11:36 -08001083 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001084 partial mac address
1085
Jon Hall42db6dc2014-10-24 19:03:48 -04001086 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001087 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001088 try:
kelvin8ec71442015-01-15 16:57:00 -08001089 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001090 return None
1091 else:
1092 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 rawHosts = self.hosts()
1094 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001095 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001097 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001098 if not host:
1099 pass
1100 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001101 return host
1102 return None
Jon Hallc6793552016-01-19 14:18:37 -08001103 except ( TypeError, ValueError ):
1104 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001105 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001106 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001107 main.log.error( self.name + ": EOF exception found" )
1108 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001109 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001110 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001111 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001112 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001113
kelvin-onlabd3b64892015-01-20 13:26:24 -08001114 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001115 """
1116 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001117 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001118
andrewonlab3f0a4af2014-10-17 12:25:14 -04001119 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001121 IMPORTANT:
1122 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001123 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001124 Furthermore, it assumes that value of VLAN is '-1'
1125 Description:
kelvin8ec71442015-01-15 16:57:00 -08001126 Converts mininet hosts ( h1, h2, h3... ) into
1127 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1128 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001129 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001130 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001131
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001133 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 hostHex = hex( int( host ) ).zfill( 12 )
1135 hostHex = str( hostHex ).replace( 'x', '0' )
1136 i = iter( str( hostHex ) )
1137 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1138 hostHex = hostHex + "/-1"
1139 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001140
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001142
Jon Halld4d4b372015-01-28 16:02:41 -08001143 except TypeError:
1144 main.log.exception( self.name + ": Object not as expected" )
1145 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001146 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001147 main.log.error( self.name + ": EOF exception found" )
1148 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001149 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001150 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001151 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001152 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001153
You Wang53dba1e2018-02-02 17:45:44 -08001154 def verifyHostIp( self, hostList=[], prefix="" ):
1155 """
1156 Description:
1157 Verify that all hosts have IP address assigned to them
1158 Optional:
1159 hostList: If specified, verifications only happen to the hosts
1160 in hostList
1161 prefix: at least one of the ip address assigned to the host
1162 needs to have the specified prefix
1163 Returns:
1164 main.TRUE if all hosts have specific IP address assigned;
1165 main.FALSE otherwise
1166 """
1167 import json
1168 try:
1169 hosts = self.hosts()
1170 hosts = json.loads( hosts )
1171 if not hostList:
1172 hostList = [ host[ "id" ] for host in hosts ]
1173 for host in hosts:
1174 hostId = host[ "id" ]
1175 if hostId not in hostList:
1176 continue
1177 ipList = host[ "ipAddresses" ]
1178 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1179 if not ipList:
1180 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1181 else:
1182 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1183 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1184 else:
1185 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1186 hostList.remove( hostId )
1187 if hostList:
1188 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1189 return main.FALSE
1190 else:
1191 return main.TRUE
1192 except KeyError:
1193 main.log.exception( self.name + ": host data not as expected: " + hosts )
1194 return None
1195 except pexpect.EOF:
1196 main.log.error( self.name + ": EOF exception found" )
1197 main.log.error( self.name + ": " + self.handle.before )
1198 main.cleanAndExit()
1199 except Exception:
1200 main.log.exception( self.name + ": Uncaught exception" )
1201 return None
1202
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001203 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001204 """
andrewonlabe6745342014-10-17 14:29:13 -04001205 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001206 * hostIdOne: ONOS host id for host1
1207 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001208 Optional:
1209 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001210 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001211 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001212 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001213 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001214 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001215 Returns:
1216 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001217 """
andrewonlabe6745342014-10-17 14:29:13 -04001218 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001219 cmdStr = "add-host-intent "
1220 if vlanId:
1221 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001222 if setVlan:
1223 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001224 if encap:
1225 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001226 if bandwidth:
1227 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001228 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001229 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001230 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001231 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001232 if re.search( "Error", handle ):
1233 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001234 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001235 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001236 else:
1237 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001238 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001239 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001240 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001241 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001242 else:
1243 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001244 main.log.debug( "Response from ONOS was: " +
1245 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001246 return None
Jon Hallc6793552016-01-19 14:18:37 -08001247 except AssertionError:
1248 main.log.exception( "" )
1249 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001250 except TypeError:
1251 main.log.exception( self.name + ": Object not as expected" )
1252 return None
andrewonlabe6745342014-10-17 14:29:13 -04001253 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001254 main.log.error( self.name + ": EOF exception found" )
1255 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001256 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001257 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001258 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001259 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001260
kelvin-onlabd3b64892015-01-20 13:26:24 -08001261 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001262 """
andrewonlab7b31d232014-10-24 13:31:47 -04001263 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001264 * ingressDevice: device id of ingress device
1265 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001266 Optional:
1267 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001268 Description:
1269 Adds an optical intent by specifying an ingress and egress device
1270 Returns:
1271 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001272 """
andrewonlab7b31d232014-10-24 13:31:47 -04001273 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001274 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1275 " " + str( egressDevice )
1276 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001277 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001278 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001279 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001280 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001281 main.log.error( "Error in adding Optical intent" )
1282 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001283 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001284 main.log.info( "Optical intent installed between " +
1285 str( ingressDevice ) + " and " +
1286 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001287 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001288 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001289 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001290 else:
1291 main.log.error( "Error, intent ID not found" )
1292 return None
Jon Hallc6793552016-01-19 14:18:37 -08001293 except AssertionError:
1294 main.log.exception( "" )
1295 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001296 except TypeError:
1297 main.log.exception( self.name + ": Object not as expected" )
1298 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001299 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001300 main.log.error( self.name + ": EOF exception found" )
1301 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001302 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001303 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001304 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001305 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001306
kelvin-onlabd3b64892015-01-20 13:26:24 -08001307 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001308 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001309 ingressDevice,
1310 egressDevice,
1311 portIngress="",
1312 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001313 ethType="",
1314 ethSrc="",
1315 ethDst="",
1316 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001317 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001318 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001319 ipProto="",
1320 ipSrc="",
1321 ipDst="",
1322 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001323 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001324 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001325 setVlan="",
1326 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001327 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001328 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001329 * ingressDevice: device id of ingress device
1330 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001331 Optional:
1332 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001333 * ethSrc: specify ethSrc ( i.e. src mac addr )
1334 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001335 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001336 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001337 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001338 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001339 * ipSrc: specify ip source address
1340 * ipDst: specify ip destination address
1341 * tcpSrc: specify tcp source port
1342 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001343 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001344 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001345 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001346 Description:
kelvin8ec71442015-01-15 16:57:00 -08001347 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001348 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001349 Returns:
1350 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001351
Jon Halle3f39ff2015-01-13 11:50:53 -08001352 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001353 options developers provide for point-to-point
1354 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001355 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001356 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001357 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001358
Jeremy Songsterff553672016-05-12 17:06:23 -07001359 if ethType:
1360 cmd += " --ethType " + str( ethType )
1361 if ethSrc:
1362 cmd += " --ethSrc " + str( ethSrc )
1363 if ethDst:
1364 cmd += " --ethDst " + str( ethDst )
1365 if bandwidth:
1366 cmd += " --bandwidth " + str( bandwidth )
1367 if lambdaAlloc:
1368 cmd += " --lambda "
1369 if ipProto:
1370 cmd += " --ipProto " + str( ipProto )
1371 if ipSrc:
1372 cmd += " --ipSrc " + str( ipSrc )
1373 if ipDst:
1374 cmd += " --ipDst " + str( ipDst )
1375 if tcpSrc:
1376 cmd += " --tcpSrc " + str( tcpSrc )
1377 if tcpDst:
1378 cmd += " --tcpDst " + str( tcpDst )
1379 if vlanId:
1380 cmd += " -v " + str( vlanId )
1381 if setVlan:
1382 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001383 if encap:
1384 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001385 if protected:
1386 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001387
kelvin8ec71442015-01-15 16:57:00 -08001388 # Check whether the user appended the port
1389 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001390 if "/" in ingressDevice:
1391 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001392 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001393 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001394 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001395 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001396 # Would it make sense to throw an exception and exit
1397 # the test?
1398 return None
andrewonlab36af3822014-11-18 17:48:18 -05001399
kelvin8ec71442015-01-15 16:57:00 -08001400 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001401 str( ingressDevice ) + "/" +\
1402 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001403
kelvin-onlabd3b64892015-01-20 13:26:24 -08001404 if "/" in egressDevice:
1405 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001406 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001407 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001408 main.log.error( "You must specify the egress port" )
1409 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001410
kelvin8ec71442015-01-15 16:57:00 -08001411 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001412 str( egressDevice ) + "/" +\
1413 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001414
kelvin-onlab898a6c62015-01-16 14:13:53 -08001415 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001416 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001417 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001418 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001419 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001420 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001421 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001422 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001423 # TODO: print out all the options in this message?
1424 main.log.info( "Point-to-point intent installed between " +
1425 str( ingressDevice ) + " and " +
1426 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001427 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001428 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001429 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001430 else:
1431 main.log.error( "Error, intent ID not found" )
1432 return None
Jon Hallc6793552016-01-19 14:18:37 -08001433 except AssertionError:
1434 main.log.exception( "" )
1435 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001436 except TypeError:
1437 main.log.exception( self.name + ": Object not as expected" )
1438 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001439 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001440 main.log.error( self.name + ": EOF exception found" )
1441 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001442 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001443 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001444 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001445 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001446
kelvin-onlabd3b64892015-01-20 13:26:24 -08001447 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001448 self,
shahshreyac2f97072015-03-19 17:04:29 -07001449 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001450 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001451 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001452 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001453 ethType="",
1454 ethSrc="",
1455 ethDst="",
1456 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001457 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001458 ipProto="",
1459 ipSrc="",
1460 ipDst="",
1461 tcpSrc="",
1462 tcpDst="",
1463 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001464 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001465 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001466 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001467 partial=False,
1468 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001469 """
shahshreyad0c80432014-12-04 16:56:05 -08001470 Note:
shahshreya70622b12015-03-19 17:19:00 -07001471 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001472 is same. That is, all ingress devices include port numbers
1473 with a "/" or all ingress devices could specify device
1474 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001475 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001476 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001477 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001478 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001479 Optional:
1480 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001481 * ethSrc: specify ethSrc ( i.e. src mac addr )
1482 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001483 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001484 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001485 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001486 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001487 * ipSrc: specify ip source address
1488 * ipDst: specify ip destination address
1489 * tcpSrc: specify tcp source port
1490 * tcpDst: specify tcp destination port
1491 * setEthSrc: action to Rewrite Source MAC Address
1492 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001493 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001494 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001495 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001496 Description:
kelvin8ec71442015-01-15 16:57:00 -08001497 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001498 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001499 Returns:
1500 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001501
Jon Halle3f39ff2015-01-13 11:50:53 -08001502 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001503 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001504 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001505 """
shahshreyad0c80432014-12-04 16:56:05 -08001506 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001507 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001508
Jeremy Songsterff553672016-05-12 17:06:23 -07001509 if ethType:
1510 cmd += " --ethType " + str( ethType )
1511 if ethSrc:
1512 cmd += " --ethSrc " + str( ethSrc )
1513 if ethDst:
1514 cmd += " --ethDst " + str( ethDst )
1515 if bandwidth:
1516 cmd += " --bandwidth " + str( bandwidth )
1517 if lambdaAlloc:
1518 cmd += " --lambda "
1519 if ipProto:
1520 cmd += " --ipProto " + str( ipProto )
1521 if ipSrc:
1522 cmd += " --ipSrc " + str( ipSrc )
1523 if ipDst:
1524 cmd += " --ipDst " + str( ipDst )
1525 if tcpSrc:
1526 cmd += " --tcpSrc " + str( tcpSrc )
1527 if tcpDst:
1528 cmd += " --tcpDst " + str( tcpDst )
1529 if setEthSrc:
1530 cmd += " --setEthSrc " + str( setEthSrc )
1531 if setEthDst:
1532 cmd += " --setEthDst " + str( setEthDst )
1533 if vlanId:
1534 cmd += " -v " + str( vlanId )
1535 if setVlan:
1536 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001537 if partial:
1538 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001539 if encap:
1540 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001541
kelvin8ec71442015-01-15 16:57:00 -08001542 # Check whether the user appended the port
1543 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001544
1545 if portIngressList is None:
1546 for ingressDevice in ingressDeviceList:
1547 if "/" in ingressDevice:
1548 cmd += " " + str( ingressDevice )
1549 else:
1550 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001551 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001552 # TODO: perhaps more meaningful return
1553 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001554 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001555 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001556 for ingressDevice, portIngress in zip( ingressDeviceList,
1557 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001558 cmd += " " + \
1559 str( ingressDevice ) + "/" +\
1560 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001561 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001562 main.log.error( "Device list and port list does not " +
1563 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001564 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001565 if "/" in egressDevice:
1566 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001567 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001568 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001569 main.log.error( "You must specify " +
1570 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001571 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001572
kelvin8ec71442015-01-15 16:57:00 -08001573 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 str( egressDevice ) + "/" +\
1575 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001576 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001577 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001578 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001579 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001580 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001581 main.log.error( "Error in adding multipoint-to-singlepoint " +
1582 "intent" )
1583 return None
shahshreyad0c80432014-12-04 16:56:05 -08001584 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001585 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001586 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001587 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001588 else:
1589 main.log.error( "Error, intent ID not found" )
1590 return None
Jon Hallc6793552016-01-19 14:18:37 -08001591 except AssertionError:
1592 main.log.exception( "" )
1593 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001594 except TypeError:
1595 main.log.exception( self.name + ": Object not as expected" )
1596 return None
1597 except pexpect.EOF:
1598 main.log.error( self.name + ": EOF exception found" )
1599 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001600 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001601 except Exception:
1602 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001603 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001604
1605 def addSinglepointToMultipointIntent(
1606 self,
1607 ingressDevice,
1608 egressDeviceList,
1609 portIngress="",
1610 portEgressList=None,
1611 ethType="",
1612 ethSrc="",
1613 ethDst="",
1614 bandwidth="",
1615 lambdaAlloc=False,
1616 ipProto="",
1617 ipSrc="",
1618 ipDst="",
1619 tcpSrc="",
1620 tcpDst="",
1621 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001622 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001623 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001624 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001625 partial=False,
1626 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001627 """
1628 Note:
1629 This function assumes the format of all egress devices
1630 is same. That is, all egress devices include port numbers
1631 with a "/" or all egress devices could specify device
1632 ids and port numbers seperately.
1633 Required:
1634 * EgressDeviceList: List of device ids of egress device
1635 ( Atleast 2 eress devices required in the list )
1636 * ingressDevice: device id of ingress device
1637 Optional:
1638 * ethType: specify ethType
1639 * ethSrc: specify ethSrc ( i.e. src mac addr )
1640 * ethDst: specify ethDst ( i.e. dst mac addr )
1641 * bandwidth: specify bandwidth capacity of link
1642 * lambdaAlloc: if True, intent will allocate lambda
1643 for the specified intent
1644 * ipProto: specify ip protocol
1645 * ipSrc: specify ip source address
1646 * ipDst: specify ip destination address
1647 * tcpSrc: specify tcp source port
1648 * tcpDst: specify tcp destination port
1649 * setEthSrc: action to Rewrite Source MAC Address
1650 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001651 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001652 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001653 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001654 Description:
1655 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1656 specifying device id's and optional fields
1657 Returns:
1658 A string of the intent id or None on error
1659
1660 NOTE: This function may change depending on the
1661 options developers provide for singlepoint-to-multipoint
1662 intent via cli
1663 """
1664 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001665 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001666
Jeremy Songsterff553672016-05-12 17:06:23 -07001667 if ethType:
1668 cmd += " --ethType " + str( ethType )
1669 if ethSrc:
1670 cmd += " --ethSrc " + str( ethSrc )
1671 if ethDst:
1672 cmd += " --ethDst " + str( ethDst )
1673 if bandwidth:
1674 cmd += " --bandwidth " + str( bandwidth )
1675 if lambdaAlloc:
1676 cmd += " --lambda "
1677 if ipProto:
1678 cmd += " --ipProto " + str( ipProto )
1679 if ipSrc:
1680 cmd += " --ipSrc " + str( ipSrc )
1681 if ipDst:
1682 cmd += " --ipDst " + str( ipDst )
1683 if tcpSrc:
1684 cmd += " --tcpSrc " + str( tcpSrc )
1685 if tcpDst:
1686 cmd += " --tcpDst " + str( tcpDst )
1687 if setEthSrc:
1688 cmd += " --setEthSrc " + str( setEthSrc )
1689 if setEthDst:
1690 cmd += " --setEthDst " + str( setEthDst )
1691 if vlanId:
1692 cmd += " -v " + str( vlanId )
1693 if setVlan:
1694 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001695 if partial:
1696 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001697 if encap:
1698 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001699
1700 # Check whether the user appended the port
1701 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001702
kelvin-onlabb9408212015-04-01 13:34:04 -07001703 if "/" in ingressDevice:
1704 cmd += " " + str( ingressDevice )
1705 else:
1706 if not portIngress:
1707 main.log.error( "You must specify " +
1708 "the Ingress port" )
1709 return main.FALSE
1710
1711 cmd += " " +\
1712 str( ingressDevice ) + "/" +\
1713 str( portIngress )
1714
1715 if portEgressList is None:
1716 for egressDevice in egressDeviceList:
1717 if "/" in egressDevice:
1718 cmd += " " + str( egressDevice )
1719 else:
1720 main.log.error( "You must specify " +
1721 "the egress port" )
1722 # TODO: perhaps more meaningful return
1723 return main.FALSE
1724 else:
1725 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001726 for egressDevice, portEgress in zip( egressDeviceList,
1727 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001728 cmd += " " + \
1729 str( egressDevice ) + "/" +\
1730 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001731 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001732 main.log.error( "Device list and port list does not " +
1733 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001734 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001735 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001736 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001737 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001738 # If error, return error message
1739 if re.search( "Error", handle ):
1740 main.log.error( "Error in adding singlepoint-to-multipoint " +
1741 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001742 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001743 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001744 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001745 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001746 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001747 else:
1748 main.log.error( "Error, intent ID not found" )
1749 return None
Jon Hallc6793552016-01-19 14:18:37 -08001750 except AssertionError:
1751 main.log.exception( "" )
1752 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001753 except TypeError:
1754 main.log.exception( self.name + ": Object not as expected" )
1755 return None
shahshreyad0c80432014-12-04 16:56:05 -08001756 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001757 main.log.error( self.name + ": EOF exception found" )
1758 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001759 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001760 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001761 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001762 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001763
Hari Krishna9e232602015-04-13 17:29:08 -07001764 def addMplsIntent(
1765 self,
1766 ingressDevice,
1767 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001768 ingressPort="",
1769 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001770 ethType="",
1771 ethSrc="",
1772 ethDst="",
1773 bandwidth="",
1774 lambdaAlloc=False,
1775 ipProto="",
1776 ipSrc="",
1777 ipDst="",
1778 tcpSrc="",
1779 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001780 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001781 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001782 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001783 """
1784 Required:
1785 * ingressDevice: device id of ingress device
1786 * egressDevice: device id of egress device
1787 Optional:
1788 * ethType: specify ethType
1789 * ethSrc: specify ethSrc ( i.e. src mac addr )
1790 * ethDst: specify ethDst ( i.e. dst mac addr )
1791 * bandwidth: specify bandwidth capacity of link
1792 * lambdaAlloc: if True, intent will allocate lambda
1793 for the specified intent
1794 * ipProto: specify ip protocol
1795 * ipSrc: specify ip source address
1796 * ipDst: specify ip destination address
1797 * tcpSrc: specify tcp source port
1798 * tcpDst: specify tcp destination port
1799 * ingressLabel: Ingress MPLS label
1800 * egressLabel: Egress MPLS label
1801 Description:
1802 Adds MPLS intent by
1803 specifying device id's and optional fields
1804 Returns:
1805 A string of the intent id or None on error
1806
1807 NOTE: This function may change depending on the
1808 options developers provide for MPLS
1809 intent via cli
1810 """
1811 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001812 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001813
Jeremy Songsterff553672016-05-12 17:06:23 -07001814 if ethType:
1815 cmd += " --ethType " + str( ethType )
1816 if ethSrc:
1817 cmd += " --ethSrc " + str( ethSrc )
1818 if ethDst:
1819 cmd += " --ethDst " + str( ethDst )
1820 if bandwidth:
1821 cmd += " --bandwidth " + str( bandwidth )
1822 if lambdaAlloc:
1823 cmd += " --lambda "
1824 if ipProto:
1825 cmd += " --ipProto " + str( ipProto )
1826 if ipSrc:
1827 cmd += " --ipSrc " + str( ipSrc )
1828 if ipDst:
1829 cmd += " --ipDst " + str( ipDst )
1830 if tcpSrc:
1831 cmd += " --tcpSrc " + str( tcpSrc )
1832 if tcpDst:
1833 cmd += " --tcpDst " + str( tcpDst )
1834 if ingressLabel:
1835 cmd += " --ingressLabel " + str( ingressLabel )
1836 if egressLabel:
1837 cmd += " --egressLabel " + str( egressLabel )
1838 if priority:
1839 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001840
1841 # Check whether the user appended the port
1842 # or provided it as an input
1843 if "/" in ingressDevice:
1844 cmd += " " + str( ingressDevice )
1845 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001846 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001847 main.log.error( "You must specify the ingress port" )
1848 return None
1849
1850 cmd += " " + \
1851 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001852 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001853
1854 if "/" in egressDevice:
1855 cmd += " " + str( egressDevice )
1856 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001857 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001858 main.log.error( "You must specify the egress port" )
1859 return None
1860
1861 cmd += " " +\
1862 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001863 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001864
1865 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001866 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001867 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001868 # If error, return error message
1869 if re.search( "Error", handle ):
1870 main.log.error( "Error in adding mpls intent" )
1871 return None
1872 else:
1873 # TODO: print out all the options in this message?
1874 main.log.info( "MPLS intent installed between " +
1875 str( ingressDevice ) + " and " +
1876 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001877 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07001878 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001879 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07001880 else:
1881 main.log.error( "Error, intent ID not found" )
1882 return None
Jon Hallc6793552016-01-19 14:18:37 -08001883 except AssertionError:
1884 main.log.exception( "" )
1885 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001886 except TypeError:
1887 main.log.exception( self.name + ": Object not as expected" )
1888 return None
1889 except pexpect.EOF:
1890 main.log.error( self.name + ": EOF exception found" )
1891 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001892 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001893 except Exception:
1894 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001895 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001896
Jon Hallefbd9792015-03-05 16:11:36 -08001897 def removeIntent( self, intentId, app='org.onosproject.cli',
1898 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001899 """
shahshreya1c818fc2015-02-26 13:44:08 -08001900 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001901 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001902 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001903 -p or --purge: Purge the intent from the store after removal
1904
Jon Halle3f39ff2015-01-13 11:50:53 -08001905 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001906 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001907 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001908 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001909 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001910 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001911 if purge:
1912 cmdStr += " -p"
1913 if sync:
1914 cmdStr += " -s"
1915
1916 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001917 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001918 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001919 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001920 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001921 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001922 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001923 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001924 # TODO: Should this be main.TRUE
1925 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001926 except AssertionError:
1927 main.log.exception( "" )
1928 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001929 except TypeError:
1930 main.log.exception( self.name + ": Object not as expected" )
1931 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001932 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001933 main.log.error( self.name + ": EOF exception found" )
1934 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001935 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001936 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001937 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001938 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04001939
YPZhangfebf7302016-05-24 16:45:56 -07001940 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001941 """
1942 Description:
1943 Remove all the intents
1944 Optional args:-
1945 -s or --sync: Waits for the removal before returning
1946 -p or --purge: Purge the intent from the store after removal
1947 Returns:
1948 Returns main.TRUE if all intents are removed, otherwise returns
1949 main.FALSE; Returns None for exception
1950 """
1951 try:
1952 cmdStr = "remove-intent"
1953 if purge:
1954 cmdStr += " -p"
1955 if sync:
1956 cmdStr += " -s"
1957
1958 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001959 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001960 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08001961 assert "Command not found:" not in handle, handle
1962 if re.search( "Error", handle ):
1963 main.log.error( "Error in removing intent" )
1964 return main.FALSE
1965 else:
1966 return main.TRUE
1967 except AssertionError:
1968 main.log.exception( "" )
1969 return None
1970 except TypeError:
1971 main.log.exception( self.name + ": Object not as expected" )
1972 return None
1973 except pexpect.EOF:
1974 main.log.error( self.name + ": EOF exception found" )
1975 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001976 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001977 except Exception:
1978 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001979 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001980
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001981 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001982 """
1983 Purges all WITHDRAWN Intents
1984 """
1985 try:
1986 cmdStr = "purge-intents"
1987 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001988 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001989 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001990 if re.search( "Error", handle ):
1991 main.log.error( "Error in purging intents" )
1992 return main.FALSE
1993 else:
1994 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001995 except AssertionError:
1996 main.log.exception( "" )
1997 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001998 except TypeError:
1999 main.log.exception( self.name + ": Object not as expected" )
2000 return None
2001 except pexpect.EOF:
2002 main.log.error( self.name + ": EOF exception found" )
2003 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002004 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002005 except Exception:
2006 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002007 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002008
Devin Lime6fe3c42017-10-18 16:28:40 -07002009 def wipeout( self ):
2010 """
2011 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2012 """
2013 try:
2014 cmdStr = "wipe-out please"
2015 handle = self.sendline( cmdStr, timeout=60 )
2016 assert handle is not None, "Error in sendline"
2017 assert "Command not found:" not in handle, handle
2018 return main.TRUE
2019 except AssertionError:
2020 main.log.exception( "" )
2021 return None
2022 except TypeError:
2023 main.log.exception( self.name + ": Object not as expected" )
2024 return None
2025 except pexpect.EOF:
2026 main.log.error( self.name + ": EOF exception found" )
2027 main.log.error( self.name + ": " + self.handle.before )
2028 main.cleanAndExit()
2029 except Exception:
2030 main.log.exception( self.name + ": Uncaught exception!" )
2031 main.cleanAndExit()
2032
kelvin-onlabd3b64892015-01-20 13:26:24 -08002033 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002034 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002035 NOTE: This method should be used after installing application:
2036 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002037 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002038 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002039 Description:
2040 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002041 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002042 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002043 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002044 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002045 cmdStr += " -j"
2046 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002047 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002048 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002049 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002050 except AssertionError:
2051 main.log.exception( "" )
2052 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002053 except TypeError:
2054 main.log.exception( self.name + ": Object not as expected" )
2055 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002056 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002057 main.log.error( self.name + ": EOF exception found" )
2058 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002059 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002060 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002061 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002062 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002063
pingping-lin54b03372015-08-13 14:43:10 -07002064 def ipv4RouteNumber( self ):
2065 """
2066 NOTE: This method should be used after installing application:
2067 onos-app-sdnip
2068 Description:
2069 Obtain the total IPv4 routes number in the system
2070 """
2071 try:
Pratik Parab57963572017-05-09 11:37:54 -07002072 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002073 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002074 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002075 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002076 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002077 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002078 except AssertionError:
2079 main.log.exception( "" )
2080 return None
2081 except ( TypeError, ValueError ):
2082 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002083 return None
2084 except pexpect.EOF:
2085 main.log.error( self.name + ": EOF exception found" )
2086 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002087 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002088 except Exception:
2089 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002090 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002091
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002092 # =============Function to check Bandwidth allocation========
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002093 def allocations( self, jsonFormat = True, dollarSign = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002094 """
2095 Description:
2096 Obtain Bandwidth Allocation Information from ONOS cli.
2097 """
2098 try:
2099 cmdStr = "allocations"
2100 if jsonFormat:
2101 cmdStr += " -j"
2102 handle = self.sendline( cmdStr, timeout=300, dollarSign=True )
2103 assert handle is not None, "Error in sendline"
2104 assert "Command not found:" not in handle, handle
2105 return handle
2106 except AssertionError:
2107 main.log.exception( "" )
2108 return None
2109 except ( TypeError, ValueError ):
2110 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2111 return None
2112 except pexpect.EOF:
2113 main.log.error( self.name + ": EOF exception found" )
2114 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002115 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002116 except Exception:
2117 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002118 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002119
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002120 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002121 """
andrewonlabe6745342014-10-17 14:29:13 -04002122 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002123 Obtain intents from the ONOS cli.
2124 Optional:
2125 * jsonFormat: Enable output formatting in json, default to True
2126 * summary: Whether only output the intent summary, defaults to False
2127 * type: Only output a certain type of intent. This options is valid
2128 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002129 """
andrewonlabe6745342014-10-17 14:29:13 -04002130 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002131 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002132 if summary:
2133 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002134 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002135 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002136 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002137 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002138 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002139 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002140 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002141 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002142 else:
Jon Hallff566d52016-01-15 14:45:36 -08002143 intentType = ""
2144 # IF we want the summary of a specific intent type
2145 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002146 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002147 if intentType in jsonResult.keys():
2148 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002149 else:
Jon Hallff566d52016-01-15 14:45:36 -08002150 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002151 return handle
2152 else:
2153 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002154 except AssertionError:
2155 main.log.exception( "" )
2156 return None
2157 except ( TypeError, ValueError ):
2158 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002159 return None
2160 except pexpect.EOF:
2161 main.log.error( self.name + ": EOF exception found" )
2162 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002163 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002164 except Exception:
2165 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002166 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002167
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002168 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002169 """
You Wangfdcbfc42016-05-16 12:16:53 -07002170 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002171 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002172 list of intent IDs.
2173 Parameters:
2174 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002175 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002176 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002177 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002178 accepted.
2179 Returns a list of dictionaries if a list of intent IDs is accepted,
2180 and each dictionary maps 'id' to the Intent ID and 'state' to
2181 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002182 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002183
kelvin-onlab54400a92015-02-26 18:05:51 -08002184 try:
2185 state = "State is Undefined"
2186 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002187 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002188 else:
Jon Hallc6793552016-01-19 14:18:37 -08002189 rawJson = intentsJson
2190 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002191 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002192 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002193 if intentsId == intent[ 'id' ]:
2194 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002195 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002196 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002197 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002198 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002199 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002200 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002201 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002202 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002203 for intent in parsedIntentsJson:
2204 if intentsId[ i ] == intent[ 'id' ]:
2205 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002206 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002207 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002208 break
Jon Hallefbd9792015-03-05 16:11:36 -08002209 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002210 main.log.warn( "Could not find all intents in ONOS output" )
2211 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002212 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002213 else:
Jon Hall53158082017-05-18 11:17:00 -07002214 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002215 return None
Jon Hallc6793552016-01-19 14:18:37 -08002216 except ( TypeError, ValueError ):
2217 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002218 return None
2219 except pexpect.EOF:
2220 main.log.error( self.name + ": EOF exception found" )
2221 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002222 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002223 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002224 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002225 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002226
Jon Hallf539eb92017-05-22 17:18:42 -07002227 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002228 """
2229 Description:
2230 Check intents state
2231 Required:
2232 intentsId - List of intents ID to be checked
2233 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002234 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002235 state in the list.
2236 *NOTE: You can pass in a list of expected state,
2237 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002238 Return:
Jon Hall53158082017-05-18 11:17:00 -07002239 Returns main.TRUE only if all intent are the same as expected states,
2240 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002241 """
2242 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002243 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002244 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002245
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002246 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002247 intentsDict = []
2248 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002249 if isinstance( intentsId, types.StringType ) \
2250 and intent.get( 'id' ) == intentsId:
2251 intentsDict.append( intent )
2252 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002253 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002254 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002255
2256 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002257 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002258 "getting intents state" )
2259 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002260
2261 if isinstance( expectedState, types.StringType ):
2262 for intents in intentsDict:
2263 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002264 main.log.debug( self.name + " : Intent ID - " +
2265 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002266 " actual state = " +
2267 intents.get( 'state' )
2268 + " does not equal expected state = "
2269 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002270 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002271 elif isinstance( expectedState, types.ListType ):
2272 for intents in intentsDict:
2273 if not any( state == intents.get( 'state' ) for state in
2274 expectedState ):
2275 main.log.debug( self.name + " : Intent ID - " +
2276 intents.get( 'id' ) +
2277 " actual state = " +
2278 intents.get( 'state' ) +
2279 " does not equal expected states = "
2280 + str( expectedState ) )
2281 returnValue = main.FALSE
2282
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002283 if returnValue == main.TRUE:
2284 main.log.info( self.name + ": All " +
2285 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002286 " intents are in " + str( expectedState ) +
2287 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002288 return returnValue
2289 except TypeError:
2290 main.log.exception( self.name + ": Object not as expected" )
2291 return None
2292 except pexpect.EOF:
2293 main.log.error( self.name + ": EOF exception found" )
2294 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002295 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002296 except Exception:
2297 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002298 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002299
Jon Hallf539eb92017-05-22 17:18:42 -07002300 def compareBandwidthAllocations( self, expectedAllocations ):
2301 """
2302 Description:
2303 Compare the allocated bandwidth with the given allocations
2304 Required:
2305 expectedAllocations - The expected ONOS output of the allocations command
2306 Return:
2307 Returns main.TRUE only if all intent are the same as expected states,
2308 otherwise returns main.FALSE.
2309 """
2310 # FIXME: Convert these string comparisons to object comparisons
2311 try:
2312 returnValue = main.TRUE
2313 bandwidthFailed = False
2314 rawAlloc = self.allocations()
2315 expectedFormat = StringIO( expectedAllocations )
2316 ONOSOutput = StringIO( rawAlloc )
2317 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2318 str( expectedFormat ) ) )
2319
2320 for actual, expected in izip( ONOSOutput, expectedFormat ):
2321 actual = actual.rstrip()
2322 expected = expected.rstrip()
2323 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2324 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002325 marker1 = actual.find( 'allocated' )
2326 m1 = actual[ :marker1 ]
2327 marker2 = expected.find( 'allocated' )
2328 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002329 if m1 != m2:
2330 bandwidthFailed = True
2331 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2332 bandwidthFailed = True
2333 expectedFormat.close()
2334 ONOSOutput.close()
2335
2336 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002337 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002338 returnValue = main.FALSE
2339 return returnValue
2340 except TypeError:
2341 main.log.exception( self.name + ": Object not as expected" )
2342 return None
2343 except pexpect.EOF:
2344 main.log.error( self.name + ": EOF exception found" )
2345 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002346 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002347 except Exception:
2348 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002349 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002350
You Wang66518af2016-05-16 15:32:59 -07002351 def compareIntent( self, intentDict ):
2352 """
2353 Description:
2354 Compare the intent ids and states provided in the argument with all intents in ONOS
2355 Return:
2356 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2357 Arguments:
2358 intentDict: a dictionary which maps intent ids to intent states
2359 """
2360 try:
2361 intentsRaw = self.intents()
2362 intentsJson = json.loads( intentsRaw )
2363 intentDictONOS = {}
2364 for intent in intentsJson:
2365 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002366 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002367 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002368 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002369 str( len( intentDict ) ) + " expected and " +
2370 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002371 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002372 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002373 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002374 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2375 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002376 else:
2377 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2378 main.log.debug( self.name + ": intent ID - " + intentID +
2379 " expected state is " + intentDict[ intentID ] +
2380 " but actual state is " + intentDictONOS[ intentID ] )
2381 returnValue = main.FALSE
2382 intentDictONOS.pop( intentID )
2383 if len( intentDictONOS ) > 0:
2384 returnValue = main.FALSE
2385 for intentID in intentDictONOS.keys():
2386 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002387 if returnValue == main.TRUE:
2388 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2389 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002390 except KeyError:
2391 main.log.exception( self.name + ": KeyError exception found" )
2392 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002393 except ( TypeError, ValueError ):
2394 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002395 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002396 except pexpect.EOF:
2397 main.log.error( self.name + ": EOF exception found" )
2398 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002399 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002400 except Exception:
2401 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002402 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002403
YPZhang14a4aa92016-07-15 13:37:15 -07002404 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002405 """
2406 Description:
2407 Check the number of installed intents.
2408 Optional:
2409 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002410 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002411 Return:
2412 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2413 , otherwise, returns main.FALSE.
2414 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002415
GlennRCed771242016-01-13 17:02:47 -08002416 try:
2417 cmd = "intents -s -j"
2418
2419 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002420 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002421 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002422 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002423 response = json.loads( response )
2424
2425 # get total and installed number, see if they are match
2426 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002427 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002428 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2429 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002430 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002431 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2432 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002433 return main.FALSE
2434
Jon Hallc6793552016-01-19 14:18:37 -08002435 except ( TypeError, ValueError ):
2436 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002437 return None
2438 except pexpect.EOF:
2439 main.log.error( self.name + ": EOF exception found" )
2440 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002441 if noExit:
2442 return main.FALSE
2443 else:
Devin Lim44075962017-08-11 10:56:37 -07002444 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002445 except pexpect.TIMEOUT:
2446 main.log.error( self.name + ": ONOS timeout" )
2447 return None
GlennRCed771242016-01-13 17:02:47 -08002448 except Exception:
2449 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002450 if noExit:
2451 return main.FALSE
2452 else:
Devin Lim44075962017-08-11 10:56:37 -07002453 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002454
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002455 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002456 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002457 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002458 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002459 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002460 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002461 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002462 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002463 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002464 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002465 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002466 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002467 if noCore:
2468 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002469 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002470 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002471 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002472 assert "Command not found:" not in handle, handle
2473 if re.search( "Error:", handle ):
2474 main.log.error( self.name + ": flows() response: " +
2475 str( handle ) )
2476 return handle
2477 except AssertionError:
2478 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002479 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002480 except TypeError:
2481 main.log.exception( self.name + ": Object not as expected" )
2482 return None
Jon Hallc6793552016-01-19 14:18:37 -08002483 except pexpect.TIMEOUT:
2484 main.log.error( self.name + ": ONOS timeout" )
2485 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002486 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002487 main.log.error( self.name + ": EOF exception found" )
2488 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002489 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002490 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002491 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002492 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002493
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002494 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002495 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002496 count = int( count ) if count else 0
2497 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002498
Jon Halle0f0b342017-04-18 11:43:47 -07002499 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002500 """
2501 Description:
GlennRCed771242016-01-13 17:02:47 -08002502 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002503 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2504 if the count of those states is 0, which means all current flows
2505 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002506 Optional:
GlennRCed771242016-01-13 17:02:47 -08002507 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002508 Return:
2509 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002510 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002511 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002512 """
2513 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002514 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002515 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002516 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002517 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002518 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002519 if rawFlows:
2520 # if we didn't get flows or flows function return None, we should return
2521 # main.Flase
2522 checkedStates.append( json.loads( rawFlows ) )
2523 else:
2524 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002525 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002526 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002527 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002528 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002529 except TypeError:
2530 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002531 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002532
GlennRCed771242016-01-13 17:02:47 -08002533 # We want to count PENDING_ADD if isPENDING is true
2534 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002535 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002536 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002537 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002538 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002539 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002540 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002541 except ( TypeError, ValueError ):
2542 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002543 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002544
YPZhang240842b2016-05-17 12:00:50 -07002545 except AssertionError:
2546 main.log.exception( "" )
2547 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002548 except pexpect.TIMEOUT:
2549 main.log.error( self.name + ": ONOS timeout" )
2550 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002551 except pexpect.EOF:
2552 main.log.error( self.name + ": EOF exception found" )
2553 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002554 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002555 except Exception:
2556 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002557 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002558
GlennRCed771242016-01-13 17:02:47 -08002559 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002560 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002561 """
andrewonlab87852b02014-11-19 18:44:19 -05002562 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002563 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002564 a specific point-to-point intent definition
2565 Required:
GlennRCed771242016-01-13 17:02:47 -08002566 * ingress: specify source dpid
2567 * egress: specify destination dpid
2568 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002569 Optional:
GlennRCed771242016-01-13 17:02:47 -08002570 * offset: the keyOffset is where the next batch of intents
2571 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002572 * noExit: If set to True, TestON will not exit if any error when issus command
2573 * getResponse: If set to True, function will return ONOS response.
2574
GlennRCed771242016-01-13 17:02:47 -08002575 Returns: If failed to push test intents, it will returen None,
2576 if successful, return true.
2577 Timeout expection will return None,
2578 TypeError will return false
2579 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002580 """
andrewonlab87852b02014-11-19 18:44:19 -05002581 try:
GlennRCed771242016-01-13 17:02:47 -08002582 if background:
2583 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002584 else:
GlennRCed771242016-01-13 17:02:47 -08002585 back = ""
2586 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002587 ingress,
2588 egress,
2589 batchSize,
2590 offset,
2591 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002592 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002593 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002594 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002595 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002596 if getResponse:
2597 return response
2598
GlennRCed771242016-01-13 17:02:47 -08002599 # TODO: We should handle if there is failure in installation
2600 return main.TRUE
2601
Jon Hallc6793552016-01-19 14:18:37 -08002602 except AssertionError:
2603 main.log.exception( "" )
2604 return None
GlennRCed771242016-01-13 17:02:47 -08002605 except pexpect.TIMEOUT:
2606 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002607 return None
andrewonlab87852b02014-11-19 18:44:19 -05002608 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002609 main.log.error( self.name + ": EOF exception found" )
2610 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002611 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002612 except TypeError:
2613 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002614 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002615 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002616 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002617 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002618
YPZhangebf9eb52016-05-12 15:20:24 -07002619 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002620 """
2621 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002622 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002623 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002624 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002625 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002626 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002627
YPZhangb5d3f832016-01-23 22:54:26 -08002628 try:
YPZhange3109a72016-02-02 11:25:37 -08002629 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002630 cmd = "flows -c added"
2631 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2632 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002633 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002634 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002635 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002636 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002637 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002638 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002639 return None
2640 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002641
You Wangd3cb2ce2016-05-16 14:01:24 -07002642 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002643 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002644 return None
2645 except pexpect.EOF:
2646 main.log.error( self.name + ": EOF exception found" )
2647 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002648 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002649 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002650 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002651 except pexpect.TIMEOUT:
2652 main.log.error( self.name + ": ONOS timeout" )
2653 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002654 except Exception:
2655 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002656 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002657 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002658 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002659
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002660 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002661 """
2662 Description:
2663 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002664 Optional:
2665 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002666 Return:
2667 The number of intents
2668 """
2669 try:
2670 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002671 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002672 if response is None:
2673 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002674 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002675 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002676 except ( TypeError, ValueError ):
2677 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002678 return None
2679 except pexpect.EOF:
2680 main.log.error( self.name + ": EOF exception found" )
2681 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002682 if noExit:
2683 return -1
2684 else:
Devin Lim44075962017-08-11 10:56:37 -07002685 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002686 except Exception:
2687 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002688 if noExit:
2689 return -1
2690 else:
Devin Lim44075962017-08-11 10:56:37 -07002691 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002692
kelvin-onlabd3b64892015-01-20 13:26:24 -08002693 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002694 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002695 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002696 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002697 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002698 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002699 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002700 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002701 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002702 cmdStr += " -j"
2703 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002704 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002705 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002706 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002707 except AssertionError:
2708 main.log.exception( "" )
2709 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002710 except TypeError:
2711 main.log.exception( self.name + ": Object not as expected" )
2712 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002713 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002714 main.log.error( self.name + ": EOF exception found" )
2715 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002716 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002717 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002718 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002719 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002720
kelvin-onlabd3b64892015-01-20 13:26:24 -08002721 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002722 """
2723 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002724 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002725 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002726 """
andrewonlab867212a2014-10-22 20:13:38 -04002727 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002728 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002729 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002730 cmdStr += " -j"
2731 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002732 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002733 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002734 if handle:
2735 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002736 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002737 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002738 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002739 else:
2740 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002741 except AssertionError:
2742 main.log.exception( "" )
2743 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002744 except TypeError:
2745 main.log.exception( self.name + ": Object not as expected" )
2746 return None
andrewonlab867212a2014-10-22 20:13:38 -04002747 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002748 main.log.error( self.name + ": EOF exception found" )
2749 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002750 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002751 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002752 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002753 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002754
kelvin8ec71442015-01-15 16:57:00 -08002755 # Wrapper functions ****************
2756 # Wrapper functions use existing driver
2757 # functions and extends their use case.
2758 # For example, we may use the output of
2759 # a normal driver function, and parse it
2760 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002761
kelvin-onlabd3b64892015-01-20 13:26:24 -08002762 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002763 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002764 Description:
2765 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002766 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002767 try:
kelvin8ec71442015-01-15 16:57:00 -08002768 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002769 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002770 if intentsStr is None:
2771 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002772 # Convert to a dictionary
2773 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002774 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002775 for intent in intents:
2776 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002777 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002778 except TypeError:
2779 main.log.exception( self.name + ": Object not as expected" )
2780 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002781 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002782 main.log.error( self.name + ": EOF exception found" )
2783 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002784 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002785 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002786 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002787 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002788
You Wang3c276252016-09-21 15:21:36 -07002789 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002790 """
2791 Determine the number of flow rules for the given device id that are
2792 in the added state
You Wang3c276252016-09-21 15:21:36 -07002793 Params:
2794 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002795 """
2796 try:
You Wang3c276252016-09-21 15:21:36 -07002797 if core:
2798 cmdStr = "flows any " + str( deviceId ) + " | " +\
2799 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2800 else:
2801 cmdStr = "flows any " + str( deviceId ) + " | " +\
2802 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002803 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002804 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002805 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002806 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002807 except AssertionError:
2808 main.log.exception( "" )
2809 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002810 except pexpect.EOF:
2811 main.log.error( self.name + ": EOF exception found" )
2812 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002813 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002814 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002815 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002816 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002817
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002818 def groupAddedCount( self, deviceId, core=False ):
2819 """
2820 Determine the number of group rules for the given device id that are
2821 in the added state
2822 Params:
2823 core: if True, only return the number of core groups added
2824 """
2825 try:
2826 if core:
2827 cmdStr = "groups any " + str( deviceId ) + " | " +\
2828 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2829 else:
2830 cmdStr = "groups any " + str( deviceId ) + " | " +\
2831 "grep 'state=ADDED' | wc -l"
2832 handle = self.sendline( cmdStr )
2833 assert handle is not None, "Error in sendline"
2834 assert "Command not found:" not in handle, handle
2835 return handle
2836 except AssertionError:
2837 main.log.exception( "" )
2838 return None
2839 except pexpect.EOF:
2840 main.log.error( self.name + ": EOF exception found" )
2841 main.log.error( self.name + ": " + self.handle.before )
2842 main.cleanAndExit()
2843 except Exception:
2844 main.log.exception( self.name + ": Uncaught exception!" )
2845 main.cleanAndExit()
2846
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002847 def addStaticRoute( self, subnet, intf):
2848 """
2849 Adds a static route to onos.
2850 Params:
2851 subnet: The subnet reaching through this route
2852 intf: The interface this route is reachable through
2853 """
2854 try:
2855 cmdStr = "route-add " + subnet + " " + intf
2856 handle = self.sendline( cmdStr )
2857 assert handle is not None, "Error in sendline"
2858 assert "Command not found:" not in handle, handle
2859 return handle
2860 except AssertionError:
2861 main.log.exception( "" )
2862 return None
2863 except pexpect.EOF:
2864 main.log.error( self.name + ": EOF exception found" )
2865 main.log.error( self.name + ": " + self.handle.before )
2866 main.cleanAndExit()
2867 except Exception:
2868 main.log.exception( self.name + ": Uncaught exception!" )
2869 main.cleanAndExit()
2870
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002871 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
2872 """
2873 Description:
2874 Check whether the number of groups for the given device id that
2875 are in ADDED state is bigger than minGroupCount.
2876 Required:
2877 * deviceId: device id to check the number of added group rules
2878 Optional:
2879 * minGroupCount: the number of groups to compare
2880 * core: if True, only check the number of core groups added
2881 * comparison: if 0, compare with greater than minFlowCount
2882 * if 1, compare with equal to minFlowCount
2883 Return:
2884 Returns the number of groups if it is bigger than minGroupCount,
2885 returns main.FALSE otherwise.
2886 """
2887 count = self.groupAddedCount( deviceId, core )
2888 count = int( count ) if count else 0
2889 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
2890
2891 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002892 """
2893 Description:
2894 Check whether the number of flow rules for the given device id that
2895 are in ADDED state is bigger than minFlowCount.
2896 Required:
2897 * deviceId: device id to check the number of added flow rules
2898 Optional:
2899 * minFlowCount: the number of flow rules to compare
2900 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002901 * comparison: if 0, compare with greater than minFlowCount
2902 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002903 Return:
2904 Returns the number of flow rules if it is bigger than minFlowCount,
2905 returns main.FALSE otherwise.
2906 """
2907 count = self.flowAddedCount( deviceId, core )
2908 count = int( count ) if count else 0
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002909 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002910
kelvin-onlabd3b64892015-01-20 13:26:24 -08002911 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002912 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002913 Use 'devices' function to obtain list of all devices
2914 and parse the result to obtain a list of all device
2915 id's. Returns this list. Returns empty list if no
2916 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002917 List is ordered sequentially
2918
andrewonlab3e15ead2014-10-15 14:21:34 -04002919 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002920 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002921 the ids. By obtaining the list of device ids on the fly,
2922 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002923 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002924 try:
kelvin8ec71442015-01-15 16:57:00 -08002925 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002926 devicesStr = self.devices( jsonFormat=False )
2927 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002928
kelvin-onlabd3b64892015-01-20 13:26:24 -08002929 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002930 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002931 return idList
kelvin8ec71442015-01-15 16:57:00 -08002932
2933 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002934 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002935 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002936 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002937 # Split list further into arguments before and after string
2938 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002939 # append to idList
2940 for arg in tempList:
2941 idList.append( arg.split( "id=" )[ 1 ] )
2942 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002943
Jon Halld4d4b372015-01-28 16:02:41 -08002944 except TypeError:
2945 main.log.exception( self.name + ": Object not as expected" )
2946 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002947 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002948 main.log.error( self.name + ": EOF exception found" )
2949 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002950 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002951 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002952 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002953 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002954
kelvin-onlabd3b64892015-01-20 13:26:24 -08002955 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002956 """
andrewonlab7c211572014-10-15 16:45:20 -04002957 Uses 'nodes' function to obtain list of all nodes
2958 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002959 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002960 Returns:
2961 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002962 """
andrewonlab7c211572014-10-15 16:45:20 -04002963 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002964 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002965 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002966 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002967 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002968 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002969 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002970 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002971 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002972 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002973 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002974 except ( TypeError, ValueError ):
2975 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002976 return None
andrewonlab7c211572014-10-15 16:45:20 -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()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002984
kelvin-onlabd3b64892015-01-20 13:26:24 -08002985 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002986 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002987 Return the first device from the devices api whose 'id' contains 'dpid'
2988 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002989 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002990 try:
kelvin8ec71442015-01-15 16:57:00 -08002991 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002992 return None
2993 else:
kelvin8ec71442015-01-15 16:57:00 -08002994 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002995 rawDevices = self.devices()
2996 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002997 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002998 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002999 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3000 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003001 return device
3002 return None
Jon Hallc6793552016-01-19 14:18:37 -08003003 except ( TypeError, ValueError ):
3004 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003005 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003006 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003007 main.log.error( self.name + ": EOF exception found" )
3008 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003009 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003010 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003011 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003012 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003013
You Wang24139872016-05-03 11:48:47 -07003014 def getTopology( self, topologyOutput ):
3015 """
3016 Definition:
3017 Loads a json topology output
3018 Return:
3019 topology = current ONOS topology
3020 """
3021 import json
3022 try:
3023 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003024 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003025 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003026 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003027 except ( TypeError, ValueError ):
3028 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3029 return None
You Wang24139872016-05-03 11:48:47 -07003030 except pexpect.EOF:
3031 main.log.error( self.name + ": EOF exception found" )
3032 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003033 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003034 except Exception:
3035 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003036 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003037
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003038 def checkStatus( self, numoswitch, numolink, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003039 """
Jon Hallefbd9792015-03-05 16:11:36 -08003040 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003041 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003042 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003043
Flavio Castro82ee2f62016-06-07 15:04:12 -07003044 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003045 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003046 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003047 logLevel = level to log to.
3048 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003049
Jon Hallefbd9792015-03-05 16:11:36 -08003050 Returns: main.TRUE if the number of switches and links are correct,
3051 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003052 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003053 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003054 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003055 try:
You Wang13310252016-07-31 10:56:14 -07003056 summary = self.summary()
3057 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003058 except ( TypeError, ValueError ):
3059 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3060 return main.ERROR
3061 try:
3062 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003063 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003064 return main.ERROR
3065 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003066 # Is the number of switches is what we expected
3067 devices = topology.get( 'devices', False )
3068 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003069 nodes = summary.get( 'nodes', False )
3070 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003071 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003072 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003073 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08003074 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003075 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3076 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003077 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003078 output = output + "The number of links and switches match "\
3079 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003080 result = main.TRUE
3081 else:
You Wang24139872016-05-03 11:48:47 -07003082 output = output + \
3083 "The number of links and switches does not match " + \
3084 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003085 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003086 output = output + "\n ONOS sees %i devices" % int( devices )
3087 output = output + " (%i expected) " % int( numoswitch )
3088 output = output + "and %i links " % int( links )
3089 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003090 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003091 output = output + "and %i controllers " % int( nodes )
3092 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003093 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003094 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003095 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003096 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003097 else:
You Wang24139872016-05-03 11:48:47 -07003098 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003099 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003100 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003101 main.log.error( self.name + ": EOF exception found" )
3102 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003103 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003104 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003105 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003106 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003107
kelvin-onlabd3b64892015-01-20 13:26:24 -08003108 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003109 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003110 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003111 deviceId must be the id of a device as seen in the onos devices command
3112 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003113 role must be either master, standby, or none
3114
Jon Halle3f39ff2015-01-13 11:50:53 -08003115 Returns:
3116 main.TRUE or main.FALSE based on argument verification and
3117 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003118 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003119 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003120 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003121 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003122 cmdStr = "device-role " +\
3123 str( deviceId ) + " " +\
3124 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003125 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003126 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003127 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003128 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003129 if re.search( "Error", handle ):
3130 # end color output to escape any colours
3131 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003132 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003133 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003134 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003135 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003136 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003137 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003138 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003139 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003140 except AssertionError:
3141 main.log.exception( "" )
3142 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003143 except TypeError:
3144 main.log.exception( self.name + ": Object not as expected" )
3145 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003146 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003147 main.log.error( self.name + ": EOF exception found" )
3148 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003149 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003150 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003151 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003152 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003153
kelvin-onlabd3b64892015-01-20 13:26:24 -08003154 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003155 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003156 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003157 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003158 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003159 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003160 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003161 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003162 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003163 cmdStr += " -j"
3164 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003165 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003166 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003167 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003168 except AssertionError:
3169 main.log.exception( "" )
3170 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003171 except TypeError:
3172 main.log.exception( self.name + ": Object not as expected" )
3173 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003174 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003175 main.log.error( self.name + ": EOF exception found" )
3176 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003177 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003178 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003179 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003180 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003181
kelvin-onlabd3b64892015-01-20 13:26:24 -08003182 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003183 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003184 CLI command to get the current leader for the Election test application
3185 NOTE: Requires installation of the onos-app-election feature
3186 Returns: Node IP of the leader if one exists
3187 None if none exists
3188 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003189 """
Jon Hall94fd0472014-12-08 11:52:42 -08003190 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003191 cmdStr = "election-test-leader"
3192 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003193 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003194 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003195 # Leader
3196 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003197 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003198 nodeSearch = re.search( leaderPattern, response )
3199 if nodeSearch:
3200 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003201 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003202 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003203 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003204 # no leader
3205 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003206 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003207 nullSearch = re.search( nullPattern, response )
3208 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003209 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003210 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003211 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003212 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003213 main.log.error( "Error in electionTestLeader on " + self.name +
3214 ": " + "unexpected response" )
3215 main.log.error( repr( response ) )
3216 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003217 except AssertionError:
3218 main.log.exception( "" )
3219 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003220 except TypeError:
3221 main.log.exception( self.name + ": Object not as expected" )
3222 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003223 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003224 main.log.error( self.name + ": EOF exception found" )
3225 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003226 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003227 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003228 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003229 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003230
kelvin-onlabd3b64892015-01-20 13:26:24 -08003231 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003232 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003233 CLI command to run for leadership of the Election test application.
3234 NOTE: Requires installation of the onos-app-election feature
3235 Returns: Main.TRUE on success
3236 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003237 """
Jon Hall94fd0472014-12-08 11:52:42 -08003238 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003239 cmdStr = "election-test-run"
3240 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003241 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003242 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003243 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003244 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003245 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003246 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003247 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003248 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003249 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003250 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003251 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003252 main.log.error( "Error in electionTestRun on " + self.name +
3253 ": " + "unexpected response" )
3254 main.log.error( repr( response ) )
3255 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003256 except AssertionError:
3257 main.log.exception( "" )
3258 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003259 except TypeError:
3260 main.log.exception( self.name + ": Object not as expected" )
3261 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003262 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003263 main.log.error( self.name + ": EOF exception found" )
3264 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003265 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003266 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003267 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003268 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003269
kelvin-onlabd3b64892015-01-20 13:26:24 -08003270 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003271 """
Jon Hall94fd0472014-12-08 11:52:42 -08003272 * CLI command to withdraw the local node from leadership election for
3273 * the Election test application.
3274 #NOTE: Requires installation of the onos-app-election feature
3275 Returns: Main.TRUE on success
3276 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003277 """
Jon Hall94fd0472014-12-08 11:52:42 -08003278 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003279 cmdStr = "election-test-withdraw"
3280 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003281 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003282 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003283 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003284 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003285 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003286 if re.search( successPattern, response ):
3287 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003288 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003289 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003290 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003291 main.log.error( "Error in electionTestWithdraw on " +
3292 self.name + ": " + "unexpected response" )
3293 main.log.error( repr( response ) )
3294 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003295 except AssertionError:
3296 main.log.exception( "" )
3297 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003298 except TypeError:
3299 main.log.exception( self.name + ": Object not as expected" )
3300 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003301 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003302 main.log.error( self.name + ": EOF exception found" )
3303 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003304 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003305 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003306 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003307 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003308
kelvin8ec71442015-01-15 16:57:00 -08003309 def getDevicePortsEnabledCount( self, dpid ):
3310 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003311 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003312 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003313 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003314 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003315 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3316 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003317 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003318 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003319 if re.search( "No such device", output ):
3320 main.log.error( "Error in getting ports" )
3321 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003322 return output
Jon Hallc6793552016-01-19 14:18:37 -08003323 except AssertionError:
3324 main.log.exception( "" )
3325 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003326 except TypeError:
3327 main.log.exception( self.name + ": Object not as expected" )
3328 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003329 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003330 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()
Jon Hallfebb1c72015-03-05 13:30:09 -08003333 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003334 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003335 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003336
kelvin8ec71442015-01-15 16:57:00 -08003337 def getDeviceLinksActiveCount( self, dpid ):
3338 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003339 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003340 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003341 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003342 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003343 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3344 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003345 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003346 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003347 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003348 main.log.error( "Error in getting ports " )
3349 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003350 return output
Jon Hallc6793552016-01-19 14:18:37 -08003351 except AssertionError:
3352 main.log.exception( "" )
3353 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003354 except TypeError:
3355 main.log.exception( self.name + ": Object not as expected" )
3356 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003357 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003358 main.log.error( self.name + ": EOF exception found" )
3359 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003360 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003361 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003362 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003363 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003364
kelvin8ec71442015-01-15 16:57:00 -08003365 def getAllIntentIds( self ):
3366 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003367 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003368 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003369 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003370 cmdStr = "onos:intents | grep id="
3371 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003372 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003373 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003374 if re.search( "Error", output ):
3375 main.log.error( "Error in getting ports" )
3376 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003377 return output
Jon Hallc6793552016-01-19 14:18:37 -08003378 except AssertionError:
3379 main.log.exception( "" )
3380 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003381 except TypeError:
3382 main.log.exception( self.name + ": Object not as expected" )
3383 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003384 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003385 main.log.error( self.name + ": EOF exception found" )
3386 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003387 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003388 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003389 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003390 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003391
Jon Hall73509952015-02-24 16:42:56 -08003392 def intentSummary( self ):
3393 """
Jon Hallefbd9792015-03-05 16:11:36 -08003394 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003395 """
3396 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003397 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003398 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003399 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003400 states.append( intent.get( 'state', None ) )
3401 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003402 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003403 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003404 except ( TypeError, ValueError ):
3405 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003406 return None
3407 except pexpect.EOF:
3408 main.log.error( self.name + ": EOF exception found" )
3409 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003410 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003411 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003412 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003413 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003414
Jon Hall61282e32015-03-19 11:34:11 -07003415 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003416 """
3417 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003418 Optional argument:
3419 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003420 """
Jon Hall63604932015-02-26 17:09:50 -08003421 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003422 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003423 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003424 cmdStr += " -j"
3425 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003426 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003427 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003428 return output
Jon Hallc6793552016-01-19 14:18:37 -08003429 except AssertionError:
3430 main.log.exception( "" )
3431 return None
Jon Hall63604932015-02-26 17:09:50 -08003432 except TypeError:
3433 main.log.exception( self.name + ": Object not as expected" )
3434 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003435 except pexpect.EOF:
3436 main.log.error( self.name + ": EOF exception found" )
3437 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003438 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003439 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003440 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003441 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003442
acsmarsa4a4d1e2015-07-10 16:01:24 -07003443 def leaderCandidates( self, jsonFormat=True ):
3444 """
3445 Returns the output of the leaders -c command.
3446 Optional argument:
3447 * jsonFormat - boolean indicating if you want output in json
3448 """
3449 try:
3450 cmdStr = "onos:leaders -c"
3451 if jsonFormat:
3452 cmdStr += " -j"
3453 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003454 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003455 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003456 return output
Jon Hallc6793552016-01-19 14:18:37 -08003457 except AssertionError:
3458 main.log.exception( "" )
3459 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003460 except TypeError:
3461 main.log.exception( self.name + ": Object not as expected" )
3462 return None
3463 except pexpect.EOF:
3464 main.log.error( self.name + ": EOF exception found" )
3465 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003466 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003467 except Exception:
3468 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003469 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003470
Jon Hallc6793552016-01-19 14:18:37 -08003471 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003472 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003473 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003474 topic parameter and an empty list if the topic doesn't exist
3475 If no leader is elected leader in the returned list will be "none"
3476 Returns None if there is a type error processing the json object
3477 """
3478 try:
Jon Hall6e709752016-02-01 13:38:46 -08003479 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003480 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003481 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003482 assert "Command not found:" not in rawOutput, rawOutput
3483 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003484 results = []
3485 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003486 if dict[ "topic" ] == topic:
3487 leader = dict[ "leader" ]
3488 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003489 results.append( leader )
3490 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003491 return results
Jon Hallc6793552016-01-19 14:18:37 -08003492 except AssertionError:
3493 main.log.exception( "" )
3494 return None
3495 except ( TypeError, ValueError ):
3496 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003497 return None
3498 except pexpect.EOF:
3499 main.log.error( self.name + ": EOF exception found" )
3500 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003501 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003502 except Exception:
3503 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003504 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003505
Jon Hall61282e32015-03-19 11:34:11 -07003506 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003507 """
3508 Returns the output of the intent Pending map.
3509 """
Jon Hall63604932015-02-26 17:09:50 -08003510 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003511 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003512 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003513 cmdStr += " -j"
3514 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003515 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003516 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003517 return output
Jon Hallc6793552016-01-19 14:18:37 -08003518 except AssertionError:
3519 main.log.exception( "" )
3520 return None
Jon Hall63604932015-02-26 17:09:50 -08003521 except TypeError:
3522 main.log.exception( self.name + ": Object not as expected" )
3523 return None
3524 except pexpect.EOF:
3525 main.log.error( self.name + ": EOF exception found" )
3526 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003527 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003528 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003529 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003530 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003531
Jon Hall2c8959e2016-12-16 12:17:34 -08003532 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003533 """
3534 Returns the output of the raft partitions command for ONOS.
3535 """
Jon Hall61282e32015-03-19 11:34:11 -07003536 # Sample JSON
3537 # {
3538 # "leader": "tcp://10.128.30.11:7238",
3539 # "members": [
3540 # "tcp://10.128.30.11:7238",
3541 # "tcp://10.128.30.17:7238",
3542 # "tcp://10.128.30.13:7238",
3543 # ],
3544 # "name": "p1",
3545 # "term": 3
3546 # },
Jon Hall63604932015-02-26 17:09:50 -08003547 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003548 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003549 if candidates:
3550 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003551 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003552 cmdStr += " -j"
3553 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003554 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003555 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003556 return output
Jon Hallc6793552016-01-19 14:18:37 -08003557 except AssertionError:
3558 main.log.exception( "" )
3559 return None
Jon Hall63604932015-02-26 17:09:50 -08003560 except TypeError:
3561 main.log.exception( self.name + ": Object not as expected" )
3562 return None
3563 except pexpect.EOF:
3564 main.log.error( self.name + ": EOF exception found" )
3565 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003566 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003567 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003568 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003569 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003570
Jon Halle9f909e2016-09-23 10:43:12 -07003571 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003572 """
3573 Returns the output of the apps command for ONOS. This command lists
3574 information about installed ONOS applications
3575 """
3576 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003577 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003578 # "description":"ONOS OpenFlow protocol southbound providers",
3579 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003580 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003581 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003582 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003583 if summary:
3584 cmdStr += " -s"
3585 if active:
3586 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003587 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003588 cmdStr += " -j"
3589 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003590 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003591 assert "Command not found:" not in output, output
3592 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003593 return output
Jon Hallbe379602015-03-24 13:39:32 -07003594 # FIXME: look at specific exceptions/Errors
3595 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003596 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003597 return None
3598 except TypeError:
3599 main.log.exception( self.name + ": Object not as expected" )
3600 return None
3601 except pexpect.EOF:
3602 main.log.error( self.name + ": EOF exception found" )
3603 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003604 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003605 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003606 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003607 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003608
Jon Hall146f1522015-03-24 15:33:24 -07003609 def appStatus( self, appName ):
3610 """
3611 Uses the onos:apps cli command to return the status of an application.
3612 Returns:
3613 "ACTIVE" - If app is installed and activated
3614 "INSTALLED" - If app is installed and deactivated
3615 "UNINSTALLED" - If app is not installed
3616 None - on error
3617 """
Jon Hall146f1522015-03-24 15:33:24 -07003618 try:
3619 if not isinstance( appName, types.StringType ):
3620 main.log.error( self.name + ".appStatus(): appName must be" +
3621 " a string" )
3622 return None
3623 output = self.apps( jsonFormat=True )
3624 appsJson = json.loads( output )
3625 state = None
3626 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003627 if appName == app.get( 'name' ):
3628 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003629 break
3630 if state == "ACTIVE" or state == "INSTALLED":
3631 return state
3632 elif state is None:
Jon Hall8bafdc02017-09-05 11:36:26 -07003633 main.log.warn( "{} app not found", appName )
Jon Hall146f1522015-03-24 15:33:24 -07003634 return "UNINSTALLED"
3635 elif state:
3636 main.log.error( "Unexpected state from 'onos:apps': " +
3637 str( state ) )
3638 return state
Jon Hallc6793552016-01-19 14:18:37 -08003639 except ( TypeError, ValueError ):
3640 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003641 return None
3642 except pexpect.EOF:
3643 main.log.error( self.name + ": EOF exception found" )
3644 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003645 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003646 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003647 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003648 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003649
Jon Hallbe379602015-03-24 13:39:32 -07003650 def app( self, appName, option ):
3651 """
3652 Interacts with the app command for ONOS. This command manages
3653 application inventory.
3654 """
Jon Hallbe379602015-03-24 13:39:32 -07003655 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003656 # Validate argument types
3657 valid = True
3658 if not isinstance( appName, types.StringType ):
3659 main.log.error( self.name + ".app(): appName must be a " +
3660 "string" )
3661 valid = False
3662 if not isinstance( option, types.StringType ):
3663 main.log.error( self.name + ".app(): option must be a string" )
3664 valid = False
3665 if not valid:
3666 return main.FALSE
3667 # Validate Option
3668 option = option.lower()
3669 # NOTE: Install may become a valid option
3670 if option == "activate":
3671 pass
3672 elif option == "deactivate":
3673 pass
3674 elif option == "uninstall":
3675 pass
3676 else:
3677 # Invalid option
3678 main.log.error( "The ONOS app command argument only takes " +
3679 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003680 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003681 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003682 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003683 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003684 assert output is not None, "Error in sendline"
3685 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003686 if "Error executing command" in output:
3687 main.log.error( "Error in processing onos:app command: " +
3688 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003689 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003690 elif "No such application" in output:
3691 main.log.error( "The application '" + appName +
3692 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003693 return main.FALSE
3694 elif "Command not found:" in output:
3695 main.log.error( "Error in processing onos:app command: " +
3696 str( output ) )
3697 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003698 elif "Unsupported command:" in output:
3699 main.log.error( "Incorrect command given to 'app': " +
3700 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003701 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003702 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003703 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003704 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003705 except AssertionError:
3706 main.log.exception( self.name + ": AssertionError exception found" )
3707 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003708 except TypeError:
3709 main.log.exception( self.name + ": Object not as expected" )
3710 return main.ERROR
3711 except pexpect.EOF:
3712 main.log.error( self.name + ": EOF exception found" )
3713 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003714 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003715 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003716 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003717 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003718
Jon Hallbd16b922015-03-26 17:53:15 -07003719 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003720 """
3721 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003722 appName is the hierarchical app name, not the feature name
3723 If check is True, method will check the status of the app after the
3724 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003725 Returns main.TRUE if the command was successfully sent
3726 main.FALSE if the cli responded with an error or given
3727 incorrect input
3728 """
3729 try:
3730 if not isinstance( appName, types.StringType ):
3731 main.log.error( self.name + ".activateApp(): appName must be" +
3732 " a string" )
3733 return main.FALSE
3734 status = self.appStatus( appName )
3735 if status == "INSTALLED":
3736 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003737 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003738 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003739 status = self.appStatus( appName )
3740 if status == "ACTIVE":
3741 return main.TRUE
3742 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003743 main.log.debug( "The state of application " +
3744 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003745 time.sleep( 1 )
3746 return main.FALSE
3747 else: # not 'check' or command didn't succeed
3748 return response
Jon Hall146f1522015-03-24 15:33:24 -07003749 elif status == "ACTIVE":
3750 return main.TRUE
3751 elif status == "UNINSTALLED":
3752 main.log.error( self.name + ": Tried to activate the " +
3753 "application '" + appName + "' which is not " +
3754 "installed." )
3755 else:
3756 main.log.error( "Unexpected return value from appStatus: " +
3757 str( status ) )
3758 return main.ERROR
3759 except TypeError:
3760 main.log.exception( self.name + ": Object not as expected" )
3761 return main.ERROR
3762 except pexpect.EOF:
3763 main.log.error( self.name + ": EOF exception found" )
3764 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003765 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003766 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003767 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003768 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003769
Jon Hallbd16b922015-03-26 17:53:15 -07003770 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003771 """
3772 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003773 appName is the hierarchical app name, not the feature name
3774 If check is True, method will check the status of the app after the
3775 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003776 Returns main.TRUE if the command was successfully sent
3777 main.FALSE if the cli responded with an error or given
3778 incorrect input
3779 """
3780 try:
3781 if not isinstance( appName, types.StringType ):
3782 main.log.error( self.name + ".deactivateApp(): appName must " +
3783 "be a string" )
3784 return main.FALSE
3785 status = self.appStatus( appName )
3786 if status == "INSTALLED":
3787 return main.TRUE
3788 elif status == "ACTIVE":
3789 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003790 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003791 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003792 status = self.appStatus( appName )
3793 if status == "INSTALLED":
3794 return main.TRUE
3795 else:
3796 time.sleep( 1 )
3797 return main.FALSE
3798 else: # not check or command didn't succeed
3799 return response
Jon Hall146f1522015-03-24 15:33:24 -07003800 elif status == "UNINSTALLED":
3801 main.log.warn( self.name + ": Tried to deactivate the " +
3802 "application '" + appName + "' which is not " +
3803 "installed." )
3804 return main.TRUE
3805 else:
3806 main.log.error( "Unexpected return value from appStatus: " +
3807 str( status ) )
3808 return main.ERROR
3809 except TypeError:
3810 main.log.exception( self.name + ": Object not as expected" )
3811 return main.ERROR
3812 except pexpect.EOF:
3813 main.log.error( self.name + ": EOF exception found" )
3814 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003815 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003816 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003817 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003818 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003819
Jon Hallbd16b922015-03-26 17:53:15 -07003820 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003821 """
3822 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003823 appName is the hierarchical app name, not the feature name
3824 If check is True, method will check the status of the app after the
3825 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003826 Returns main.TRUE if the command was successfully sent
3827 main.FALSE if the cli responded with an error or given
3828 incorrect input
3829 """
3830 # TODO: check with Thomas about the state machine for apps
3831 try:
3832 if not isinstance( appName, types.StringType ):
3833 main.log.error( self.name + ".uninstallApp(): appName must " +
3834 "be a string" )
3835 return main.FALSE
3836 status = self.appStatus( appName )
3837 if status == "INSTALLED":
3838 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003839 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003840 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003841 status = self.appStatus( appName )
3842 if status == "UNINSTALLED":
3843 return main.TRUE
3844 else:
3845 time.sleep( 1 )
3846 return main.FALSE
3847 else: # not check or command didn't succeed
3848 return response
Jon Hall146f1522015-03-24 15:33:24 -07003849 elif status == "ACTIVE":
3850 main.log.warn( self.name + ": Tried to uninstall the " +
3851 "application '" + appName + "' which is " +
3852 "currently active." )
3853 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003854 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003855 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003856 status = self.appStatus( appName )
3857 if status == "UNINSTALLED":
3858 return main.TRUE
3859 else:
3860 time.sleep( 1 )
3861 return main.FALSE
3862 else: # not check or command didn't succeed
3863 return response
Jon Hall146f1522015-03-24 15:33:24 -07003864 elif status == "UNINSTALLED":
3865 return main.TRUE
3866 else:
3867 main.log.error( "Unexpected return value from appStatus: " +
3868 str( status ) )
3869 return main.ERROR
3870 except TypeError:
3871 main.log.exception( self.name + ": Object not as expected" )
3872 return main.ERROR
3873 except pexpect.EOF:
3874 main.log.error( self.name + ": EOF exception found" )
3875 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003876 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003877 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003878 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003879 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003880
3881 def appIDs( self, jsonFormat=True ):
3882 """
3883 Show the mappings between app id and app names given by the 'app-ids'
3884 cli command
3885 """
3886 try:
3887 cmdStr = "app-ids"
3888 if jsonFormat:
3889 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003890 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003891 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003892 assert "Command not found:" not in output, output
3893 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003894 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003895 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003896 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003897 return None
3898 except TypeError:
3899 main.log.exception( self.name + ": Object not as expected" )
3900 return None
3901 except pexpect.EOF:
3902 main.log.error( self.name + ": EOF exception found" )
3903 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003904 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003905 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003906 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003907 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003908
3909 def appToIDCheck( self ):
3910 """
3911 This method will check that each application's ID listed in 'apps' is
3912 the same as the ID listed in 'app-ids'. The check will also check that
3913 there are no duplicate IDs issued. Note that an app ID should be
3914 a globaly unique numerical identifier for app/app-like features. Once
3915 an ID is registered, the ID is never freed up so that if an app is
3916 reinstalled it will have the same ID.
3917
3918 Returns: main.TRUE if the check passes and
3919 main.FALSE if the check fails or
3920 main.ERROR if there is some error in processing the test
3921 """
3922 try:
Jon Hall390696c2015-05-05 17:13:41 -07003923 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003924 rawJson = self.appIDs( jsonFormat=True )
3925 if rawJson:
3926 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003927 else:
Jon Hallc6793552016-01-19 14:18:37 -08003928 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003929 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003930 rawJson = self.apps( jsonFormat=True )
3931 if rawJson:
3932 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003933 else:
Jon Hallc6793552016-01-19 14:18:37 -08003934 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003935 bail = True
3936 if bail:
3937 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003938 result = main.TRUE
3939 for app in apps:
3940 appID = app.get( 'id' )
3941 if appID is None:
3942 main.log.error( "Error parsing app: " + str( app ) )
3943 result = main.FALSE
3944 appName = app.get( 'name' )
3945 if appName is None:
3946 main.log.error( "Error parsing app: " + str( app ) )
3947 result = main.FALSE
3948 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003949 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07003950 if not current: # if ids doesn't have this id
3951 result = main.FALSE
3952 main.log.error( "'app-ids' does not have the ID for " +
3953 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08003954 main.log.debug( "apps command returned: " + str( app ) +
3955 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003956 elif len( current ) > 1:
3957 # there is more than one app with this ID
3958 result = main.FALSE
3959 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003960 elif not current[ 0 ][ 'name' ] == appName:
3961 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07003962 result = main.FALSE
3963 main.log.error( "'app-ids' has " + str( currentName ) +
3964 " registered under id:" + str( appID ) +
3965 " but 'apps' has " + str( appName ) )
3966 else:
3967 pass # id and name match!
3968 # now make sure that app-ids has no duplicates
3969 idsList = []
3970 namesList = []
3971 for item in ids:
3972 idsList.append( item[ 'id' ] )
3973 namesList.append( item[ 'name' ] )
3974 if len( idsList ) != len( set( idsList ) ) or\
3975 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003976 main.log.error( "'app-ids' has some duplicate entries: \n"
3977 + json.dumps( ids,
3978 sort_keys=True,
3979 indent=4,
3980 separators=( ',', ': ' ) ) )
3981 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003982 return result
Jon Hallc6793552016-01-19 14:18:37 -08003983 except ( TypeError, ValueError ):
3984 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003985 return main.ERROR
3986 except pexpect.EOF:
3987 main.log.error( self.name + ": EOF exception found" )
3988 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003989 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003990 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003991 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003992 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003993
Jon Hallfb760a02015-04-13 15:35:03 -07003994 def getCfg( self, component=None, propName=None, short=False,
3995 jsonFormat=True ):
3996 """
3997 Get configuration settings from onos cli
3998 Optional arguments:
3999 component - Optionally only list configurations for a specific
4000 component. If None, all components with configurations
4001 are displayed. Case Sensitive string.
4002 propName - If component is specified, propName option will show
4003 only this specific configuration from that component.
4004 Case Sensitive string.
4005 jsonFormat - Returns output as json. Note that this will override
4006 the short option
4007 short - Short, less verbose, version of configurations.
4008 This is overridden by the json option
4009 returns:
4010 Output from cli as a string or None on error
4011 """
4012 try:
4013 baseStr = "cfg"
4014 cmdStr = " get"
4015 componentStr = ""
4016 if component:
4017 componentStr += " " + component
4018 if propName:
4019 componentStr += " " + propName
4020 if jsonFormat:
4021 baseStr += " -j"
4022 elif short:
4023 baseStr += " -s"
4024 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004025 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004026 assert "Command not found:" not in output, output
4027 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004028 return output
4029 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004030 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004031 return None
4032 except TypeError:
4033 main.log.exception( self.name + ": Object not as expected" )
4034 return None
4035 except pexpect.EOF:
4036 main.log.error( self.name + ": EOF exception found" )
4037 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004038 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004039 except Exception:
4040 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004041 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004042
4043 def setCfg( self, component, propName, value=None, check=True ):
4044 """
4045 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004046 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004047 component - The case sensitive name of the component whose
4048 property is to be set
4049 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004050 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004051 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004052 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004053 check - Boolean, Check whether the option was successfully set this
4054 only applies when a value is given.
4055 returns:
4056 main.TRUE on success or main.FALSE on failure. If check is False,
4057 will return main.TRUE unless there is an error
4058 """
4059 try:
4060 baseStr = "cfg"
4061 cmdStr = " set " + str( component ) + " " + str( propName )
4062 if value is not None:
4063 cmdStr += " " + str( value )
4064 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004065 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004066 assert "Command not found:" not in output, output
4067 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004068 if value and check:
4069 results = self.getCfg( component=str( component ),
4070 propName=str( propName ),
4071 jsonFormat=True )
4072 # Check if current value is what we just set
4073 try:
4074 jsonOutput = json.loads( results )
4075 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004076 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004077 main.log.exception( "Error parsing cfg output" )
4078 main.log.error( "output:" + repr( results ) )
4079 return main.FALSE
4080 if current == str( value ):
4081 return main.TRUE
4082 return main.FALSE
4083 return main.TRUE
4084 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004085 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004086 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004087 except ( TypeError, ValueError ):
4088 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004089 return main.FALSE
4090 except pexpect.EOF:
4091 main.log.error( self.name + ": EOF exception found" )
4092 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004093 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004094 except Exception:
4095 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004096 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004097
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004098 def distPrimitivesSend( self, cmd ):
4099 """
4100 Function to handle sending cli commands for the distributed primitives test app
4101
4102 This command will catch some exceptions and retry the command on some
4103 specific store exceptions.
4104
4105 Required arguments:
4106 cmd - The command to send to the cli
4107 returns:
4108 string containing the cli output
4109 None on Error
4110 """
4111 try:
4112 output = self.sendline( cmd )
4113 try:
4114 assert output is not None, "Error in sendline"
4115 # TODO: Maybe make this less hardcoded
4116 # ConsistentMap Exceptions
4117 assert "org.onosproject.store.service" not in output
4118 # Node not leader
4119 assert "java.lang.IllegalStateException" not in output
4120 except AssertionError:
4121 main.log.error( "Error in processing '" + cmd + "' " +
4122 "command: " + str( output ) )
4123 retryTime = 30 # Conservative time, given by Madan
4124 main.log.info( "Waiting " + str( retryTime ) +
4125 "seconds before retrying." )
4126 time.sleep( retryTime ) # Due to change in mastership
4127 output = self.sendline( cmd )
4128 assert output is not None, "Error in sendline"
4129 assert "Command not found:" not in output, output
4130 assert "Error executing command" not in output, output
4131 main.log.info( self.name + ": " + output )
4132 return output
4133 except AssertionError:
4134 main.log.exception( "Error in processing '" + cmd + "' command." )
4135 return None
4136 except TypeError:
4137 main.log.exception( self.name + ": Object not as expected" )
4138 return None
4139 except pexpect.EOF:
4140 main.log.error( self.name + ": EOF exception found" )
4141 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004142 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004143 except Exception:
4144 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004145 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004146
Jon Hall390696c2015-05-05 17:13:41 -07004147 def setTestAdd( self, setName, values ):
4148 """
4149 CLI command to add elements to a distributed set.
4150 Arguments:
4151 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004152 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004153 Example usages:
4154 setTestAdd( "set1", "a b c" )
4155 setTestAdd( "set2", "1" )
4156 returns:
4157 main.TRUE on success OR
4158 main.FALSE if elements were already in the set OR
4159 main.ERROR on error
4160 """
4161 try:
4162 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004163 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004164 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4165 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004166 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004167 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004168 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004169 return main.FALSE
4170 else:
4171 main.log.error( self.name + ": setTestAdd did not" +
4172 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004173 main.log.debug( self.name + " actual: " + repr( output ) )
4174 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004175 except TypeError:
4176 main.log.exception( self.name + ": Object not as expected" )
4177 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004178 except Exception:
4179 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004180 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004181
4182 def setTestRemove( self, setName, values, clear=False, retain=False ):
4183 """
4184 CLI command to remove elements from a distributed set.
4185 Required arguments:
4186 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004187 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004188 Optional arguments:
4189 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004190 retain - Retain only the given values. (intersection of the
4191 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004192 returns:
4193 main.TRUE on success OR
4194 main.FALSE if the set was not changed OR
4195 main.ERROR on error
4196 """
4197 try:
4198 cmdStr = "set-test-remove "
4199 if clear:
4200 cmdStr += "-c " + str( setName )
4201 elif retain:
4202 cmdStr += "-r " + str( setName ) + " " + str( values )
4203 else:
4204 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004205 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004206 if clear:
4207 pattern = "Set " + str( setName ) + " cleared"
4208 if re.search( pattern, output ):
4209 return main.TRUE
4210 elif retain:
4211 positivePattern = str( setName ) + " was pruned to contain " +\
4212 "only elements of set \[(.*)\]"
4213 negativePattern = str( setName ) + " was not changed by " +\
4214 "retaining only elements of the set " +\
4215 "\[(.*)\]"
4216 if re.search( positivePattern, output ):
4217 return main.TRUE
4218 elif re.search( negativePattern, output ):
4219 return main.FALSE
4220 else:
4221 positivePattern = "\[(.*)\] was removed from the set " +\
4222 str( setName )
4223 if ( len( values.split() ) == 1 ):
4224 negativePattern = "\[(.*)\] was not in set " +\
4225 str( setName )
4226 else:
4227 negativePattern = "No element of \[(.*)\] was in set " +\
4228 str( setName )
4229 if re.search( positivePattern, output ):
4230 return main.TRUE
4231 elif re.search( negativePattern, output ):
4232 return main.FALSE
4233 main.log.error( self.name + ": setTestRemove did not" +
4234 " match expected output" )
4235 main.log.debug( self.name + " expected: " + pattern )
4236 main.log.debug( self.name + " actual: " + repr( output ) )
4237 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004238 except TypeError:
4239 main.log.exception( self.name + ": Object not as expected" )
4240 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004241 except Exception:
4242 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004243 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004244
4245 def setTestGet( self, setName, values="" ):
4246 """
4247 CLI command to get the elements in a distributed set.
4248 Required arguments:
4249 setName - The name of the set to remove from.
4250 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004251 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004252 returns:
4253 main.ERROR on error OR
4254 A list of elements in the set if no optional arguments are
4255 supplied OR
4256 A tuple containing the list then:
4257 main.FALSE if the given values are not in the set OR
4258 main.TRUE if the given values are in the set OR
4259 """
4260 try:
4261 values = str( values ).strip()
4262 setName = str( setName ).strip()
4263 length = len( values.split() )
4264 containsCheck = None
4265 # Patterns to match
4266 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004267 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004268 containsTrue = "Set " + setName + " contains the value " + values
4269 containsFalse = "Set " + setName + " did not contain the value " +\
4270 values
4271 containsAllTrue = "Set " + setName + " contains the the subset " +\
4272 setPattern
4273 containsAllFalse = "Set " + setName + " did not contain the the" +\
4274 " subset " + setPattern
4275
4276 cmdStr = "set-test-get "
4277 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004278 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004279 if length == 0:
4280 match = re.search( pattern, output )
4281 else: # if given values
4282 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004283 patternTrue = pattern + "\r\n" + containsTrue
4284 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004285 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004286 patternTrue = pattern + "\r\n" + containsAllTrue
4287 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004288 matchTrue = re.search( patternTrue, output )
4289 matchFalse = re.search( patternFalse, output )
4290 if matchTrue:
4291 containsCheck = main.TRUE
4292 match = matchTrue
4293 elif matchFalse:
4294 containsCheck = main.FALSE
4295 match = matchFalse
4296 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004297 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004298 "expected output" )
4299 main.log.debug( self.name + " expected: " + pattern )
4300 main.log.debug( self.name + " actual: " + repr( output ) )
4301 match = None
4302 if match:
4303 setMatch = match.group( 1 )
4304 if setMatch == '':
4305 setList = []
4306 else:
4307 setList = setMatch.split( ", " )
4308 if length > 0:
4309 return ( setList, containsCheck )
4310 else:
4311 return setList
4312 else: # no match
4313 main.log.error( self.name + ": setTestGet did not" +
4314 " match expected output" )
4315 main.log.debug( self.name + " expected: " + pattern )
4316 main.log.debug( self.name + " actual: " + repr( output ) )
4317 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004318 except TypeError:
4319 main.log.exception( self.name + ": Object not as expected" )
4320 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004321 except Exception:
4322 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004323 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004324
4325 def setTestSize( self, setName ):
4326 """
4327 CLI command to get the elements in a distributed set.
4328 Required arguments:
4329 setName - The name of the set to remove from.
4330 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004331 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004332 None on error
4333 """
4334 try:
4335 # TODO: Should this check against the number of elements returned
4336 # and then return true/false based on that?
4337 setName = str( setName ).strip()
4338 # Patterns to match
4339 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004340 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004341 setPattern
4342 cmdStr = "set-test-get -s "
4343 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004344 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004345 match = re.search( pattern, output )
4346 if match:
4347 setSize = int( match.group( 1 ) )
4348 setMatch = match.group( 2 )
4349 if len( setMatch.split() ) == setSize:
4350 main.log.info( "The size returned by " + self.name +
4351 " matches the number of elements in " +
4352 "the returned set" )
4353 else:
4354 main.log.error( "The size returned by " + self.name +
4355 " does not match the number of " +
4356 "elements in the returned set." )
4357 return setSize
4358 else: # no match
4359 main.log.error( self.name + ": setTestGet did not" +
4360 " match expected output" )
4361 main.log.debug( self.name + " expected: " + pattern )
4362 main.log.debug( self.name + " actual: " + repr( output ) )
4363 return None
Jon Hall390696c2015-05-05 17:13:41 -07004364 except TypeError:
4365 main.log.exception( self.name + ": Object not as expected" )
4366 return None
Jon Hall390696c2015-05-05 17:13:41 -07004367 except Exception:
4368 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004369 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004370
Jon Hall80daded2015-05-27 16:07:00 -07004371 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004372 """
4373 Command to list the various counters in the system.
4374 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004375 if jsonFormat, a string of the json object returned by the cli
4376 command
4377 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004378 None on error
4379 """
Jon Hall390696c2015-05-05 17:13:41 -07004380 try:
Jon Hall390696c2015-05-05 17:13:41 -07004381 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004382 if jsonFormat:
4383 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004384 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004385 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004386 assert "Command not found:" not in output, output
4387 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004388 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004389 return output
Jon Hall390696c2015-05-05 17:13:41 -07004390 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004391 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004392 return None
Jon Hall390696c2015-05-05 17:13:41 -07004393 except TypeError:
4394 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004395 return None
Jon Hall390696c2015-05-05 17:13:41 -07004396 except pexpect.EOF:
4397 main.log.error( self.name + ": EOF exception found" )
4398 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004399 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004400 except Exception:
4401 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004402 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004403
Jon Hall935db192016-04-19 00:22:04 -07004404 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004405 """
Jon Halle1a3b752015-07-22 13:02:46 -07004406 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004407 Required arguments:
4408 counter - The name of the counter to increment.
4409 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004410 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004411 returns:
4412 integer value of the counter or
4413 None on Error
4414 """
4415 try:
4416 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004417 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004418 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004419 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004420 if delta != 1:
4421 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004422 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004423 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004424 match = re.search( pattern, output )
4425 if match:
4426 return int( match.group( 1 ) )
4427 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004428 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004429 " match expected output." )
4430 main.log.debug( self.name + " expected: " + pattern )
4431 main.log.debug( self.name + " actual: " + repr( output ) )
4432 return None
Jon Hall390696c2015-05-05 17:13:41 -07004433 except TypeError:
4434 main.log.exception( self.name + ": Object not as expected" )
4435 return None
Jon Hall390696c2015-05-05 17:13:41 -07004436 except Exception:
4437 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004438 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004439
Jon Hall935db192016-04-19 00:22:04 -07004440 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004441 """
4442 CLI command to get a distributed counter then add a delta to it.
4443 Required arguments:
4444 counter - The name of the counter to increment.
4445 Optional arguments:
4446 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004447 returns:
4448 integer value of the counter or
4449 None on Error
4450 """
4451 try:
4452 counter = str( counter )
4453 delta = int( delta )
4454 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004455 cmdStr += counter
4456 if delta != 1:
4457 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004458 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004459 pattern = counter + " was updated to (-?\d+)"
4460 match = re.search( pattern, output )
4461 if match:
4462 return int( match.group( 1 ) )
4463 else:
4464 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4465 " match expected output." )
4466 main.log.debug( self.name + " expected: " + pattern )
4467 main.log.debug( self.name + " actual: " + repr( output ) )
4468 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004469 except TypeError:
4470 main.log.exception( self.name + ": Object not as expected" )
4471 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004472 except Exception:
4473 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004474 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004475
4476 def valueTestGet( self, valueName ):
4477 """
4478 CLI command to get the value of an atomic value.
4479 Required arguments:
4480 valueName - The name of the value to get.
4481 returns:
4482 string value of the value or
4483 None on Error
4484 """
4485 try:
4486 valueName = str( valueName )
4487 cmdStr = "value-test "
4488 operation = "get"
4489 cmdStr = "value-test {} {}".format( valueName,
4490 operation )
4491 output = self.distPrimitivesSend( cmdStr )
4492 pattern = "(\w+)"
4493 match = re.search( pattern, output )
4494 if match:
4495 return match.group( 1 )
4496 else:
4497 main.log.error( self.name + ": valueTestGet did not" +
4498 " match expected output." )
4499 main.log.debug( self.name + " expected: " + pattern )
4500 main.log.debug( self.name + " actual: " + repr( output ) )
4501 return None
4502 except TypeError:
4503 main.log.exception( self.name + ": Object not as expected" )
4504 return None
4505 except Exception:
4506 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004507 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004508
4509 def valueTestSet( self, valueName, newValue ):
4510 """
4511 CLI command to set the value of an atomic value.
4512 Required arguments:
4513 valueName - The name of the value to set.
4514 newValue - The value to assign to the given value.
4515 returns:
4516 main.TRUE on success or
4517 main.ERROR on Error
4518 """
4519 try:
4520 valueName = str( valueName )
4521 newValue = str( newValue )
4522 operation = "set"
4523 cmdStr = "value-test {} {} {}".format( valueName,
4524 operation,
4525 newValue )
4526 output = self.distPrimitivesSend( cmdStr )
4527 if output is not None:
4528 return main.TRUE
4529 else:
4530 return main.ERROR
4531 except TypeError:
4532 main.log.exception( self.name + ": Object not as expected" )
4533 return main.ERROR
4534 except Exception:
4535 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004536 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004537
4538 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4539 """
4540 CLI command to compareAndSet the value of an atomic value.
4541 Required arguments:
4542 valueName - The name of the value.
4543 oldValue - Compare the current value of the atomic value to this
4544 newValue - If the value equals oldValue, set the value to newValue
4545 returns:
4546 main.TRUE on success or
4547 main.FALSE on failure or
4548 main.ERROR on Error
4549 """
4550 try:
4551 valueName = str( valueName )
4552 oldValue = str( oldValue )
4553 newValue = str( newValue )
4554 operation = "compareAndSet"
4555 cmdStr = "value-test {} {} {} {}".format( valueName,
4556 operation,
4557 oldValue,
4558 newValue )
4559 output = self.distPrimitivesSend( cmdStr )
4560 pattern = "(\w+)"
4561 match = re.search( pattern, output )
4562 if match:
4563 result = match.group( 1 )
4564 if result == "true":
4565 return main.TRUE
4566 elif result == "false":
4567 return main.FALSE
4568 else:
4569 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4570 " match expected output." )
4571 main.log.debug( self.name + " expected: " + pattern )
4572 main.log.debug( self.name + " actual: " + repr( output ) )
4573 return main.ERROR
4574 except TypeError:
4575 main.log.exception( self.name + ": Object not as expected" )
4576 return main.ERROR
4577 except Exception:
4578 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004579 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004580
4581 def valueTestGetAndSet( self, valueName, newValue ):
4582 """
4583 CLI command to getAndSet the value of an atomic value.
4584 Required arguments:
4585 valueName - The name of the value to get.
4586 newValue - The value to assign to the given value
4587 returns:
4588 string value of the value or
4589 None on Error
4590 """
4591 try:
4592 valueName = str( valueName )
4593 cmdStr = "value-test "
4594 operation = "getAndSet"
4595 cmdStr += valueName + " " + operation
4596 cmdStr = "value-test {} {} {}".format( valueName,
4597 operation,
4598 newValue )
4599 output = self.distPrimitivesSend( cmdStr )
4600 pattern = "(\w+)"
4601 match = re.search( pattern, output )
4602 if match:
4603 return match.group( 1 )
4604 else:
4605 main.log.error( self.name + ": valueTestGetAndSet did not" +
4606 " match expected output." )
4607 main.log.debug( self.name + " expected: " + pattern )
4608 main.log.debug( self.name + " actual: " + repr( output ) )
4609 return None
4610 except TypeError:
4611 main.log.exception( self.name + ": Object not as expected" )
4612 return None
4613 except Exception:
4614 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004615 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004616
4617 def valueTestDestroy( self, valueName ):
4618 """
4619 CLI command to destroy an atomic value.
4620 Required arguments:
4621 valueName - The name of the value to destroy.
4622 returns:
4623 main.TRUE on success or
4624 main.ERROR on Error
4625 """
4626 try:
4627 valueName = str( valueName )
4628 cmdStr = "value-test "
4629 operation = "destroy"
4630 cmdStr += valueName + " " + operation
4631 output = self.distPrimitivesSend( cmdStr )
4632 if output is not None:
4633 return main.TRUE
4634 else:
4635 return main.ERROR
4636 except TypeError:
4637 main.log.exception( self.name + ": Object not as expected" )
4638 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004639 except Exception:
4640 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004641 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004642
YPZhangfebf7302016-05-24 16:45:56 -07004643 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004644 """
4645 Description: Execute summary command in onos
4646 Returns: json object ( summary -j ), returns main.FALSE if there is
4647 no output
4648
4649 """
4650 try:
4651 cmdStr = "summary"
4652 if jsonFormat:
4653 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004654 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004655 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004656 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004657 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004658 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004659 if not handle:
4660 main.log.error( self.name + ": There is no output in " +
4661 "summary command" )
4662 return main.FALSE
4663 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004664 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004665 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004666 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004667 except TypeError:
4668 main.log.exception( self.name + ": Object not as expected" )
4669 return None
4670 except pexpect.EOF:
4671 main.log.error( self.name + ": EOF exception found" )
4672 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004673 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004674 except Exception:
4675 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004676 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004677
Jon Hall935db192016-04-19 00:22:04 -07004678 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004679 """
4680 CLI command to get the value of a key in a consistent map using
4681 transactions. This a test function and can only get keys from the
4682 test map hard coded into the cli command
4683 Required arguments:
4684 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004685 returns:
4686 The string value of the key or
4687 None on Error
4688 """
4689 try:
4690 keyName = str( keyName )
4691 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004692 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004693 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004694 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4695 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004696 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004697 return None
4698 else:
4699 match = re.search( pattern, output )
4700 if match:
4701 return match.groupdict()[ 'value' ]
4702 else:
4703 main.log.error( self.name + ": transactionlMapGet did not" +
4704 " match expected output." )
4705 main.log.debug( self.name + " expected: " + pattern )
4706 main.log.debug( self.name + " actual: " + repr( output ) )
4707 return None
4708 except TypeError:
4709 main.log.exception( self.name + ": Object not as expected" )
4710 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004711 except Exception:
4712 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004713 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004714
Jon Hall935db192016-04-19 00:22:04 -07004715 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004716 """
4717 CLI command to put a value into 'numKeys' number of keys in a
4718 consistent map using transactions. This a test function and can only
4719 put into keys named 'Key#' of the test map hard coded into the cli command
4720 Required arguments:
4721 numKeys - Number of keys to add the value to
4722 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004723 returns:
4724 A dictionary whose keys are the name of the keys put into the map
4725 and the values of the keys are dictionaries whose key-values are
4726 'value': value put into map and optionaly
4727 'oldValue': Previous value in the key or
4728 None on Error
4729
4730 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004731 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4732 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004733 """
4734 try:
4735 numKeys = str( numKeys )
4736 value = str( value )
4737 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004738 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004739 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004740 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4741 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4742 results = {}
4743 for line in output.splitlines():
4744 new = re.search( newPattern, line )
4745 updated = re.search( updatedPattern, line )
4746 if new:
4747 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4748 elif updated:
4749 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004750 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004751 else:
4752 main.log.error( self.name + ": transactionlMapGet did not" +
4753 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004754 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4755 newPattern,
4756 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004757 main.log.debug( self.name + " actual: " + repr( output ) )
4758 return results
4759 except TypeError:
4760 main.log.exception( self.name + ": Object not as expected" )
4761 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004762 except Exception:
4763 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004764 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004765
acsmarsdaea66c2015-09-03 11:44:06 -07004766 def maps( self, jsonFormat=True ):
4767 """
4768 Description: Returns result of onos:maps
4769 Optional:
4770 * jsonFormat: enable json formatting of output
4771 """
4772 try:
4773 cmdStr = "maps"
4774 if jsonFormat:
4775 cmdStr += " -j"
4776 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004777 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004778 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004779 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004780 except AssertionError:
4781 main.log.exception( "" )
4782 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004783 except TypeError:
4784 main.log.exception( self.name + ": Object not as expected" )
4785 return None
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()
acsmarsdaea66c2015-09-03 11:44:06 -07004790 except Exception:
4791 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004792 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004793
4794 def getSwController( self, uri, jsonFormat=True ):
4795 """
4796 Descrition: Gets the controller information from the device
4797 """
4798 try:
4799 cmd = "device-controllers "
4800 if jsonFormat:
4801 cmd += "-j "
4802 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004803 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004804 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004805 return response
Jon Hallc6793552016-01-19 14:18:37 -08004806 except AssertionError:
4807 main.log.exception( "" )
4808 return None
GlennRC050596c2015-11-18 17:06:41 -08004809 except TypeError:
4810 main.log.exception( self.name + ": Object not as expected" )
4811 return None
4812 except pexpect.EOF:
4813 main.log.error( self.name + ": EOF exception found" )
4814 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004815 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004816 except Exception:
4817 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004818 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004819
4820 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4821 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004822 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004823
4824 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004825 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08004826 ip - String or List: The ip address of the controller.
4827 This parameter can be formed in a couple of different ways.
4828 VALID:
4829 10.0.0.1 - just the ip address
4830 tcp:10.0.0.1 - the protocol and the ip address
4831 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4832 so that you can add controllers with different
4833 protocols and ports
4834 INVALID:
4835 10.0.0.1:6653 - this is not supported by ONOS
4836
4837 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4838 port - The port number.
4839 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4840
4841 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4842 """
4843 try:
4844 cmd = "device-setcontrollers"
4845
4846 if jsonFormat:
4847 cmd += " -j"
4848 cmd += " " + uri
4849 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004850 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08004851 for item in ip:
4852 if ":" in item:
4853 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004854 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08004855 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004856 elif "." in sitem[ 1 ]:
4857 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08004858 else:
4859 main.log.error( "Malformed entry: " + item )
4860 raise TypeError
4861 else:
4862 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004863 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004864 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004865 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004866 if "Error" in response:
4867 main.log.error( response )
4868 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004869 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004870 except AssertionError:
4871 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004872 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004873 except TypeError:
4874 main.log.exception( self.name + ": Object not as expected" )
4875 return main.FALSE
4876 except pexpect.EOF:
4877 main.log.error( self.name + ": EOF exception found" )
4878 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004879 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004880 except Exception:
4881 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004882 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004883
4884 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004885 '''
GlennRC20fc6522015-12-23 23:26:57 -08004886 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004887 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08004888 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004889 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08004890 Returns:
4891 Returns main.FALSE if an exception is thrown or an error is present
4892 in the response. Otherwise, returns main.TRUE.
4893 NOTE:
4894 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004895 '''
GlennRC20fc6522015-12-23 23:26:57 -08004896 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004897 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07004898 deviceStr = device
4899 device = []
4900 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004901
4902 for d in device:
4903 time.sleep( 1 )
4904 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004905 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004906 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004907 if "Error" in response:
4908 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4909 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004910 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004911 except AssertionError:
4912 main.log.exception( "" )
4913 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004914 except TypeError:
4915 main.log.exception( self.name + ": Object not as expected" )
4916 return main.FALSE
4917 except pexpect.EOF:
4918 main.log.error( self.name + ": EOF exception found" )
4919 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004920 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004921 except Exception:
4922 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004923 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004924
4925 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004926 '''
GlennRC20fc6522015-12-23 23:26:57 -08004927 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004928 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08004929 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004930 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08004931 Returns:
4932 Returns main.FALSE if an exception is thrown or an error is present
4933 in the response. Otherwise, returns main.TRUE.
4934 NOTE:
4935 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004936 '''
GlennRC20fc6522015-12-23 23:26:57 -08004937 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004938 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08004939 host = list( host )
4940
4941 for h in host:
4942 time.sleep( 1 )
4943 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004944 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004945 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004946 if "Error" in response:
4947 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4948 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004949 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004950 except AssertionError:
4951 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004952 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004953 except TypeError:
4954 main.log.exception( self.name + ": Object not as expected" )
4955 return main.FALSE
4956 except pexpect.EOF:
4957 main.log.error( self.name + ": EOF exception found" )
4958 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004959 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004960 except Exception:
4961 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004962 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004963
YPZhangfebf7302016-05-24 16:45:56 -07004964 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004965 '''
GlennRCed771242016-01-13 17:02:47 -08004966 Description:
4967 Bring link down or up in the null-provider.
4968 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004969 begin - (string) One end of a device or switch.
4970 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08004971 returns:
4972 main.TRUE if no exceptions were thrown and no Errors are
4973 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004974 '''
GlennRCed771242016-01-13 17:02:47 -08004975 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004976 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004977 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004978 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004979 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004980 if "Error" in response or "Failure" in response:
4981 main.log.error( response )
4982 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004983 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004984 except AssertionError:
4985 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004986 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004987 except TypeError:
4988 main.log.exception( self.name + ": Object not as expected" )
4989 return main.FALSE
4990 except pexpect.EOF:
4991 main.log.error( self.name + ": EOF exception found" )
4992 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004993 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004994 except Exception:
4995 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004996 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004997
Jon Hall2c8959e2016-12-16 12:17:34 -08004998 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004999 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005000 Description:
5001 Changes the state of port in an OF switch by means of the
5002 PORTSTATUS OF messages.
5003 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005004 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5005 port - (string) target port in the device. Ex: '2'
5006 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005007 returns:
5008 main.TRUE if no exceptions were thrown and no Errors are
5009 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005010 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005011 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005012 state = state.lower()
5013 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005014 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005015 response = self.sendline( cmd, showResponse=True )
5016 assert response is not None, "Error in sendline"
5017 assert "Command not found:" not in response, response
5018 if "Error" in response or "Failure" in response:
5019 main.log.error( response )
5020 return main.FALSE
5021 return main.TRUE
5022 except AssertionError:
5023 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005024 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005025 except TypeError:
5026 main.log.exception( self.name + ": Object not as expected" )
5027 return main.FALSE
5028 except pexpect.EOF:
5029 main.log.error( self.name + ": EOF exception found" )
5030 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005031 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005032 except Exception:
5033 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005034 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005035
5036 def logSet( self, level="INFO", app="org.onosproject" ):
5037 """
5038 Set the logging level to lvl for a specific app
5039 returns main.TRUE on success
5040 returns main.FALSE if Error occurred
5041 if noExit is True, TestON will not exit, but clean up
5042 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5043 Level defaults to INFO
5044 """
5045 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005046 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005047 self.handle.expect( "onos>" )
5048
5049 response = self.handle.before
5050 if re.search( "Error", response ):
5051 return main.FALSE
5052 return main.TRUE
5053 except pexpect.TIMEOUT:
5054 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005055 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005056 except pexpect.EOF:
5057 main.log.error( self.name + ": EOF exception found" )
5058 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005059 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005060 except Exception:
5061 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005062 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005063
5064 def getGraphDict( self, timeout=60, includeHost=False ):
5065 """
5066 Return a dictionary which describes the latest network topology data as a
5067 graph.
5068 An example of the dictionary:
5069 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5070 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5071 Each vertex should at least have an 'edges' attribute which describes the
5072 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005073 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005074 list of attributes.
5075 An example of the edges dictionary:
5076 'edges': { vertex2: { 'port': ..., 'weight': ... },
5077 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005078 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005079 in topology data.
5080 """
5081 graphDict = {}
5082 try:
5083 links = self.links()
5084 links = json.loads( links )
5085 devices = self.devices()
5086 devices = json.loads( devices )
5087 idToDevice = {}
5088 for device in devices:
5089 idToDevice[ device[ 'id' ] ] = device
5090 if includeHost:
5091 hosts = self.hosts()
5092 # FIXME: support 'includeHost' argument
5093 for link in links:
5094 nodeA = link[ 'src' ][ 'device' ]
5095 nodeB = link[ 'dst' ][ 'device' ]
5096 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005097 if nodeA not in graphDict.keys():
5098 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005099 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005100 'type': idToDevice[ nodeA ][ 'type' ],
5101 'available': idToDevice[ nodeA ][ 'available' ],
5102 'role': idToDevice[ nodeA ][ 'role' ],
5103 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5104 'hw': idToDevice[ nodeA ][ 'hw' ],
5105 'sw': idToDevice[ nodeA ][ 'sw' ],
5106 'serial': idToDevice[ nodeA ][ 'serial' ],
5107 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005108 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005109 else:
5110 # Assert nodeB is not connected to any current links of nodeA
5111 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005112 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5113 'type': link[ 'type' ],
5114 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005115 return graphDict
5116 except ( TypeError, ValueError ):
5117 main.log.exception( self.name + ": Object not as expected" )
5118 return None
5119 except KeyError:
5120 main.log.exception( self.name + ": KeyError exception found" )
5121 return None
5122 except AssertionError:
5123 main.log.exception( self.name + ": AssertionError exception found" )
5124 return None
5125 except pexpect.EOF:
5126 main.log.error( self.name + ": EOF exception found" )
5127 main.log.error( self.name + ": " + self.handle.before )
5128 return None
5129 except Exception:
5130 main.log.exception( self.name + ": Uncaught exception!" )
5131 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005132
5133 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005134 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005135 Send command to check intent-perf summary
5136 Returns: dictionary for intent-perf summary
5137 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005138 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005139 cmd = "intent-perf -s"
5140 respDic = {}
5141 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005142 assert resp is not None, "Error in sendline"
5143 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005144 try:
5145 # Generate the dictionary to return
5146 for l in resp.split( "\n" ):
5147 # Delete any white space in line
5148 temp = re.sub( r'\s+', '', l )
5149 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005150 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005151
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005152 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005153 main.log.exception( self.name + ": Object not as expected" )
5154 return None
5155 except KeyError:
5156 main.log.exception( self.name + ": KeyError exception found" )
5157 return None
5158 except AssertionError:
5159 main.log.exception( self.name + ": AssertionError exception found" )
5160 return None
5161 except pexpect.EOF:
5162 main.log.error( self.name + ": EOF exception found" )
5163 main.log.error( self.name + ": " + self.handle.before )
5164 return None
5165 except Exception:
5166 main.log.exception( self.name + ": Uncaught exception!" )
5167 return None
5168 return respDic
5169
Chiyu Chengec63bde2016-11-17 18:11:36 -08005170 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005171 """
5172 Searches the latest ONOS log file for the given search term and
5173 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005174
chengchiyu08303a02016-09-08 17:40:26 -07005175 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005176 searchTerm:
5177 The string to grep from the ONOS log.
5178 startLine:
5179 The term that decides which line is the start to search the searchTerm in
5180 the karaf log. For now, startTerm only works in 'first' mode.
5181 logNum:
5182 In some extreme cases, one karaf log is not big enough to contain all the
5183 information.Because of this, search mutiply logs is necessary to capture
5184 the right result. logNum is the number of karaf logs that we need to search
5185 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005186 mode:
5187 all: return all the strings that contain the search term
5188 last: return the last string that contains the search term
5189 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005190 num: return the number of times that the searchTerm appears in the log
5191 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005192 """
5193 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005194 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005195 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005196 logPath = '/opt/onos/log/karaf.log.'
5197 logPaths = '/opt/onos/log/karaf.log'
5198 for i in range( 1, logNum ):
5199 logPaths = logPath + str( i ) + " " + logPaths
5200 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005201 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005202 # 100000000 is just a extreme large number to make sure this function can
5203 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005204 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005205 if mode == 'all':
5206 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005207 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005208 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005209 elif mode == 'first':
5210 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5211 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005212 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005213 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005214 return num
You Wang6d301d42017-04-21 10:49:33 -07005215 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005216 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005217 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005218 else:
5219 main.log.error( self.name + " unsupported mode" )
5220 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005221 before = self.sendline( cmd )
5222 before = before.splitlines()
5223 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005224 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005225 return returnLines
5226 except AssertionError:
5227 main.log.error( self.name + " searchTerm is not string type" )
5228 return None
5229 except pexpect.EOF:
5230 main.log.error( self.name + ": EOF exception found" )
5231 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005232 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005233 except pexpect.TIMEOUT:
5234 main.log.error( self.name + ": TIMEOUT exception found" )
5235 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005236 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005237 except Exception:
5238 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005239 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005240
5241 def vplsShow( self, jsonFormat=True ):
5242 """
5243 Description: Returns result of onos:vpls show, which should list the
5244 configured VPLS networks and the assigned interfaces.
5245 Optional:
5246 * jsonFormat: enable json formatting of output
5247 Returns:
5248 The output of the command or None on error.
5249 """
5250 try:
5251 cmdStr = "vpls show"
5252 if jsonFormat:
5253 raise NotImplementedError
5254 cmdStr += " -j"
5255 handle = self.sendline( cmdStr )
5256 assert handle is not None, "Error in sendline"
5257 assert "Command not found:" not in handle, handle
5258 return handle
5259 except AssertionError:
5260 main.log.exception( "" )
5261 return None
5262 except TypeError:
5263 main.log.exception( self.name + ": Object not as expected" )
5264 return None
5265 except pexpect.EOF:
5266 main.log.error( self.name + ": EOF exception found" )
5267 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005268 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005269 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005270 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005271 return None
5272 except Exception:
5273 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005274 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005275
5276 def parseVplsShow( self ):
5277 """
5278 Parse the cli output of 'vpls show' into json output. This is required
5279 as there is currently no json output available.
5280 """
5281 try:
5282 output = []
5283 raw = self.vplsShow( jsonFormat=False )
5284 namePat = "VPLS name: (?P<name>\w+)"
5285 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5286 encapPat = "Encapsulation: (?P<encap>\w+)"
5287 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5288 mIter = re.finditer( pattern, raw )
5289 for match in mIter:
5290 item = {}
5291 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005292 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005293 if ifaces == [ "" ]:
5294 ifaces = []
5295 item[ 'interfaces' ] = ifaces
5296 encap = match.group( 'encap' )
5297 if encap != 'NONE':
5298 item[ 'encapsulation' ] = encap.lower()
5299 output.append( item )
5300 return output
5301 except Exception:
5302 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005303 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005304
5305 def vplsList( self, jsonFormat=True ):
5306 """
5307 Description: Returns result of onos:vpls list, which should list the
5308 configured VPLS networks.
5309 Optional:
5310 * jsonFormat: enable json formatting of output
5311 """
5312 try:
5313 cmdStr = "vpls list"
5314 if jsonFormat:
5315 raise NotImplementedError
5316 cmdStr += " -j"
5317 handle = self.sendline( cmdStr )
5318 assert handle is not None, "Error in sendline"
5319 assert "Command not found:" not in handle, handle
5320 return handle
5321 except AssertionError:
5322 main.log.exception( "" )
5323 return None
5324 except TypeError:
5325 main.log.exception( self.name + ": Object not as expected" )
5326 return None
5327 except pexpect.EOF:
5328 main.log.error( self.name + ": EOF exception found" )
5329 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005330 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005331 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005332 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005333 return None
5334 except Exception:
5335 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005336 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005337
5338 def vplsCreate( self, network ):
5339 """
5340 CLI command to create a new VPLS network.
5341 Required arguments:
5342 network - String name of the network to create.
5343 returns:
5344 main.TRUE on success and main.FALSE on failure
5345 """
5346 try:
5347 network = str( network )
5348 cmdStr = "vpls create "
5349 cmdStr += network
5350 output = self.sendline( cmdStr )
5351 assert output is not None, "Error in sendline"
5352 assert "Command not found:" not in output, output
5353 assert "Error executing command" not in output, output
5354 assert "VPLS already exists:" not in output, output
5355 return main.TRUE
5356 except AssertionError:
5357 main.log.exception( "" )
5358 return main.FALSE
5359 except TypeError:
5360 main.log.exception( self.name + ": Object not as expected" )
5361 return main.FALSE
5362 except pexpect.EOF:
5363 main.log.error( self.name + ": EOF exception found" )
5364 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005365 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005366 except Exception:
5367 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005368 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005369
5370 def vplsDelete( self, network ):
5371 """
5372 CLI command to delete a VPLS network.
5373 Required arguments:
5374 network - Name of the network to delete.
5375 returns:
5376 main.TRUE on success and main.FALSE on failure
5377 """
5378 try:
5379 network = str( network )
5380 cmdStr = "vpls delete "
5381 cmdStr += network
5382 output = self.sendline( cmdStr )
5383 assert output is not None, "Error in sendline"
5384 assert "Command not found:" not in output, output
5385 assert "Error executing command" not in output, output
5386 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005387 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005388 return main.TRUE
5389 except AssertionError:
5390 main.log.exception( "" )
5391 return main.FALSE
5392 except TypeError:
5393 main.log.exception( self.name + ": Object not as expected" )
5394 return main.FALSE
5395 except pexpect.EOF:
5396 main.log.error( self.name + ": EOF exception found" )
5397 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005398 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005399 except Exception:
5400 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005401 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005402
5403 def vplsAddIface( self, network, iface ):
5404 """
5405 CLI command to add an interface to a VPLS network.
5406 Required arguments:
5407 network - Name of the network to add the interface to.
5408 iface - The ONOS name for an interface.
5409 returns:
5410 main.TRUE on success and main.FALSE on failure
5411 """
5412 try:
5413 network = str( network )
5414 iface = str( iface )
5415 cmdStr = "vpls add-if "
5416 cmdStr += network + " " + iface
5417 output = self.sendline( cmdStr )
5418 assert output is not None, "Error in sendline"
5419 assert "Command not found:" not in output, output
5420 assert "Error executing command" not in output, output
5421 assert "already associated to network" not in output, output
5422 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005423 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005424 return main.TRUE
5425 except AssertionError:
5426 main.log.exception( "" )
5427 return main.FALSE
5428 except TypeError:
5429 main.log.exception( self.name + ": Object not as expected" )
5430 return main.FALSE
5431 except pexpect.EOF:
5432 main.log.error( self.name + ": EOF exception found" )
5433 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005434 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005435 except Exception:
5436 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005437 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005438
5439 def vplsRemIface( self, network, iface ):
5440 """
5441 CLI command to remove an interface from a VPLS network.
5442 Required arguments:
5443 network - Name of the network to remove the interface from.
5444 iface - Name of the interface to remove.
5445 returns:
5446 main.TRUE on success and main.FALSE on failure
5447 """
5448 try:
5449 iface = str( iface )
5450 cmdStr = "vpls rem-if "
5451 cmdStr += network + " " + iface
5452 output = self.sendline( cmdStr )
5453 assert output is not None, "Error in sendline"
5454 assert "Command not found:" not in output, output
5455 assert "Error executing command" not in output, output
5456 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005457 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005458 return main.TRUE
5459 except AssertionError:
5460 main.log.exception( "" )
5461 return main.FALSE
5462 except TypeError:
5463 main.log.exception( self.name + ": Object not as expected" )
5464 return main.FALSE
5465 except pexpect.EOF:
5466 main.log.error( self.name + ": EOF exception found" )
5467 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005468 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005469 except Exception:
5470 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005471 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005472
5473 def vplsClean( self ):
5474 """
5475 Description: Clears the VPLS app configuration.
5476 Returns: main.TRUE on success and main.FALSE on failure
5477 """
5478 try:
5479 cmdStr = "vpls clean"
5480 handle = self.sendline( cmdStr )
5481 assert handle is not None, "Error in sendline"
5482 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005483 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005484 return handle
5485 except AssertionError:
5486 main.log.exception( "" )
5487 return main.FALSE
5488 except TypeError:
5489 main.log.exception( self.name + ": Object not as expected" )
5490 return main.FALSE
5491 except pexpect.EOF:
5492 main.log.error( self.name + ": EOF exception found" )
5493 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005494 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005495 except Exception:
5496 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005497 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005498
5499 def vplsSetEncap( self, network, encapType ):
5500 """
5501 CLI command to add an interface to a VPLS network.
5502 Required arguments:
5503 network - Name of the network to create.
5504 encapType - Type of encapsulation.
5505 returns:
5506 main.TRUE on success and main.FALSE on failure
5507 """
5508 try:
5509 network = str( network )
5510 encapType = str( encapType ).upper()
5511 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5512 cmdStr = "vpls set-encap "
5513 cmdStr += network + " " + encapType
5514 output = self.sendline( cmdStr )
5515 assert output is not None, "Error in sendline"
5516 assert "Command not found:" not in output, output
5517 assert "Error executing command" not in output, output
5518 assert "already associated to network" not in output, output
5519 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005520 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005521 return main.TRUE
5522 except AssertionError:
5523 main.log.exception( "" )
5524 return main.FALSE
5525 except TypeError:
5526 main.log.exception( self.name + ": Object not as expected" )
5527 return main.FALSE
5528 except pexpect.EOF:
5529 main.log.error( self.name + ": EOF exception found" )
5530 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005531 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005532 except Exception:
5533 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005534 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005535
5536 def interfaces( self, jsonFormat=True ):
5537 """
5538 Description: Returns result of interfaces command.
5539 Optional:
5540 * jsonFormat: enable json formatting of output
5541 Returns:
5542 The output of the command or None on error.
5543 """
5544 try:
5545 cmdStr = "interfaces"
5546 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005547 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005548 cmdStr += " -j"
5549 handle = self.sendline( cmdStr )
5550 assert handle is not None, "Error in sendline"
5551 assert "Command not found:" not in handle, handle
5552 return handle
5553 except AssertionError:
5554 main.log.exception( "" )
5555 return None
5556 except TypeError:
5557 main.log.exception( self.name + ": Object not as expected" )
5558 return None
5559 except pexpect.EOF:
5560 main.log.error( self.name + ": EOF exception found" )
5561 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005562 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005563 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005564 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005565 return None
5566 except Exception:
5567 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005568 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005569
5570 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005571 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005572 Get the timestamp of searchTerm from karaf log.
5573
5574 Arguments:
5575 splitTerm_before and splitTerm_after:
5576
5577 The terms that split the string that contains the timeStamp of
5578 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5579 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5580 and the splitTerm_after is "x"
5581
5582 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005583 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005584 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005585 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005586 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005587 return main.ERROR
5588 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005589 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005590 main.log.warn( "Captured timestamp string is empty" )
5591 return main.ERROR
5592 lines = lines[ 0 ]
5593 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005594 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005595 # get the target value
5596 line = lines.split( splitTerm_before )
5597 key = line[ 1 ].split( splitTerm_after )
5598 return int( key[ 0 ] )
5599 except IndexError:
5600 main.log.warn( "Index Error!" )
5601 return main.ERROR
5602 except AssertionError:
5603 main.log.warn( "Search Term Not Found " )
5604 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005605
5606 def workQueueAdd( self, queueName, value ):
5607 """
5608 CLI command to add a string to the specified Work Queue.
5609 This function uses the distributed primitives test app, which
5610 gives some cli access to distributed primitives for testing
5611 purposes only.
5612
5613 Required arguments:
5614 queueName - The name of the queue to add to
5615 value - The value to add to the queue
5616 returns:
5617 main.TRUE on success, main.FALSE on failure and
5618 main.ERROR on error.
5619 """
5620 try:
5621 queueName = str( queueName )
5622 value = str( value )
5623 prefix = "work-queue-test"
5624 operation = "add"
5625 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5626 output = self.distPrimitivesSend( cmdStr )
5627 if "Invalid operation name" in output:
5628 main.log.warn( output )
5629 return main.ERROR
5630 elif "Done" in output:
5631 return main.TRUE
5632 except TypeError:
5633 main.log.exception( self.name + ": Object not as expected" )
5634 return main.ERROR
5635 except Exception:
5636 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005637 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005638
5639 def workQueueAddMultiple( self, queueName, value1, value2 ):
5640 """
5641 CLI command to add two strings to the specified Work Queue.
5642 This function uses the distributed primitives test app, which
5643 gives some cli access to distributed primitives for testing
5644 purposes only.
5645
5646 Required arguments:
5647 queueName - The name of the queue to add to
5648 value1 - The first value to add to the queue
5649 value2 - The second value to add to the queue
5650 returns:
5651 main.TRUE on success, main.FALSE on failure and
5652 main.ERROR on error.
5653 """
5654 try:
5655 queueName = str( queueName )
5656 value1 = str( value1 )
5657 value2 = str( value2 )
5658 prefix = "work-queue-test"
5659 operation = "addMultiple"
5660 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5661 output = self.distPrimitivesSend( cmdStr )
5662 if "Invalid operation name" in output:
5663 main.log.warn( output )
5664 return main.ERROR
5665 elif "Done" in output:
5666 return main.TRUE
5667 except TypeError:
5668 main.log.exception( self.name + ": Object not as expected" )
5669 return main.ERROR
5670 except Exception:
5671 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005672 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005673
5674 def workQueueTakeAndComplete( self, queueName, number=1 ):
5675 """
5676 CLI command to take a value from the specified Work Queue and compelte it.
5677 This function uses the distributed primitives test app, which
5678 gives some cli access to distributed primitives for testing
5679 purposes only.
5680
5681 Required arguments:
5682 queueName - The name of the queue to add to
5683 number - The number of items to take and complete
5684 returns:
5685 main.TRUE on success, main.FALSE on failure and
5686 main.ERROR on error.
5687 """
5688 try:
5689 queueName = str( queueName )
5690 number = str( int( number ) )
5691 prefix = "work-queue-test"
5692 operation = "takeAndComplete"
5693 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5694 output = self.distPrimitivesSend( cmdStr )
5695 if "Invalid operation name" in output:
5696 main.log.warn( output )
5697 return main.ERROR
5698 elif "Done" in output:
5699 return main.TRUE
5700 except TypeError:
5701 main.log.exception( self.name + ": Object not as expected" )
5702 return main.ERROR
5703 except Exception:
5704 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005705 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005706
5707 def workQueueDestroy( self, queueName ):
5708 """
5709 CLI command to destroy the specified Work Queue.
5710 This function uses the distributed primitives test app, which
5711 gives some cli access to distributed primitives for testing
5712 purposes only.
5713
5714 Required arguments:
5715 queueName - The name of the queue to add to
5716 returns:
5717 main.TRUE on success, main.FALSE on failure and
5718 main.ERROR on error.
5719 """
5720 try:
5721 queueName = str( queueName )
5722 prefix = "work-queue-test"
5723 operation = "destroy"
5724 cmdStr = " ".join( [ prefix, queueName, operation ] )
5725 output = self.distPrimitivesSend( cmdStr )
5726 if "Invalid operation name" in output:
5727 main.log.warn( output )
5728 return main.ERROR
5729 return main.TRUE
5730 except TypeError:
5731 main.log.exception( self.name + ": Object not as expected" )
5732 return main.ERROR
5733 except Exception:
5734 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005735 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005736
5737 def workQueueTotalPending( self, queueName ):
5738 """
5739 CLI command to get the Total Pending items of the specified Work Queue.
5740 This function uses the distributed primitives test app, which
5741 gives some cli access to distributed primitives for testing
5742 purposes only.
5743
5744 Required arguments:
5745 queueName - The name of the queue to add to
5746 returns:
5747 The number of Pending items in the specified work queue or
5748 None on error
5749 """
5750 try:
5751 queueName = str( queueName )
5752 prefix = "work-queue-test"
5753 operation = "totalPending"
5754 cmdStr = " ".join( [ prefix, queueName, operation ] )
5755 output = self.distPrimitivesSend( cmdStr )
5756 pattern = r'\d+'
5757 if "Invalid operation name" in output:
5758 main.log.warn( output )
5759 return None
5760 else:
5761 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005762 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005763 except ( AttributeError, TypeError ):
5764 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5765 return None
5766 except Exception:
5767 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005768 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005769
5770 def workQueueTotalCompleted( self, queueName ):
5771 """
5772 CLI command to get the Total Completed items of the specified Work Queue.
5773 This function uses the distributed primitives test app, which
5774 gives some cli access to distributed primitives for testing
5775 purposes only.
5776
5777 Required arguments:
5778 queueName - The name of the queue to add to
5779 returns:
5780 The number of complete items in the specified work queue or
5781 None on error
5782 """
5783 try:
5784 queueName = str( queueName )
5785 prefix = "work-queue-test"
5786 operation = "totalCompleted"
5787 cmdStr = " ".join( [ prefix, queueName, operation ] )
5788 output = self.distPrimitivesSend( cmdStr )
5789 pattern = r'\d+'
5790 if "Invalid operation name" in output:
5791 main.log.warn( output )
5792 return None
5793 else:
5794 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005795 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005796 except ( AttributeError, TypeError ):
5797 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5798 return None
5799 except Exception:
5800 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005801 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005802
5803 def workQueueTotalInProgress( self, queueName ):
5804 """
5805 CLI command to get the Total In Progress items of the specified Work Queue.
5806 This function uses the distributed primitives test app, which
5807 gives some cli access to distributed primitives for testing
5808 purposes only.
5809
5810 Required arguments:
5811 queueName - The name of the queue to add to
5812 returns:
5813 The number of In Progress items in the specified work queue or
5814 None on error
5815 """
5816 try:
5817 queueName = str( queueName )
5818 prefix = "work-queue-test"
5819 operation = "totalInProgress"
5820 cmdStr = " ".join( [ prefix, queueName, operation ] )
5821 output = self.distPrimitivesSend( cmdStr )
5822 pattern = r'\d+'
5823 if "Invalid operation name" in output:
5824 main.log.warn( output )
5825 return None
5826 else:
5827 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005828 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005829 except ( AttributeError, TypeError ):
5830 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5831 return None
5832 except Exception:
5833 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005834 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005835
5836 def events( self, args='-a' ):
5837 """
5838 Description: Returns events -a command output
5839 Optional:
5840 add other arguments
5841 """
5842 try:
5843 cmdStr = "events"
5844 if args:
5845 cmdStr += " " + args
5846 handle = self.sendline( cmdStr )
5847 assert handle is not None, "Error in sendline"
5848 assert "Command not found:" not in handle, handle
5849 return handle
5850 except AssertionError:
5851 main.log.exception( "" )
5852 return None
5853 except TypeError:
5854 main.log.exception( self.name + ": Object not as expected" )
5855 return None
5856 except pexpect.EOF:
5857 main.log.error( self.name + ": EOF exception found" )
5858 main.log.error( self.name + ": " + self.handle.before )
5859 main.cleanAndExit()
5860 except Exception:
5861 main.log.exception( self.name + ": Uncaught exception!" )
5862 main.cleanAndExit()
5863
5864 def getMaster( self, deviceID ):
5865 """
5866 Description: Obtains current master using "roles" command for a specific deviceID
5867 """
5868 try:
5869 return str( self.getRole( deviceID )[ 'master' ] )
5870 except AssertionError:
5871 main.log.exception( "" )
5872 return None
5873 except TypeError:
5874 main.log.exception( self.name + ": Object not as expected" )
5875 return None
5876 except pexpect.EOF:
5877 main.log.error( self.name + ": EOF exception found" )
5878 main.log.error( self.name + ": " + self.handle.before )
5879 main.cleanAndExit()
5880 except Exception:
5881 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07005882 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08005883
5884 def issu( self ):
5885 """
5886 Short summary of In-Service Software Upgrade status
5887
5888 Returns the output of the cli command or None on Error
5889 """
5890 try:
5891 cmdStr = "issu"
5892 handle = self.sendline( cmdStr )
5893 assert handle is not None, "Error in sendline"
5894 assert "Command not found:" not in handle, handle
5895 assert "Unsupported command:" not in handle, handle
5896 return handle
5897 except AssertionError:
5898 main.log.exception( "" )
5899 return None
5900 except TypeError:
5901 main.log.exception( self.name + ": Object not as expected" )
5902 return None
5903 except pexpect.EOF:
5904 main.log.error( self.name + ": EOF exception found" )
5905 main.log.error( self.name + ": " + self.handle.before )
5906 main.cleanAndExit()
5907 except Exception:
5908 main.log.exception( self.name + ": Uncaught exception!" )
5909 main.cleanAndExit()
5910
5911 def issuInit( self ):
5912 """
5913 Initiates an In-Service Software Upgrade
5914
5915 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5916 """
5917 try:
5918 cmdStr = "issu init"
5919 handle = self.sendline( cmdStr )
5920 assert handle is not None, "Error in sendline"
5921 assert "Command not found:" not in handle, handle
5922 assert "Unsupported command:" not in handle, handle
5923 if "Initialized" in handle:
5924 return main.TRUE
5925 else:
5926 return main.FALSE
5927 except AssertionError:
5928 main.log.exception( "" )
5929 return main.ERROR
5930 except TypeError:
5931 main.log.exception( self.name + ": Object not as expected" )
5932 return main.ERROR
5933 except pexpect.EOF:
5934 main.log.error( self.name + ": EOF exception found" )
5935 main.log.error( self.name + ": " + self.handle.before )
5936 main.cleanAndExit()
5937 except Exception:
5938 main.log.exception( self.name + ": Uncaught exception!" )
5939 main.cleanAndExit()
5940
5941 def issuUpgrade( self ):
5942 """
5943 Transitions stores to upgraded nodes
5944
5945 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5946 """
5947 try:
5948 cmdStr = "issu upgrade"
5949 handle = self.sendline( cmdStr )
5950 assert handle is not None, "Error in sendline"
5951 assert "Command not found:" not in handle, handle
5952 assert "Unsupported command:" not in handle, handle
5953 if "Upgraded" in handle:
5954 return main.TRUE
5955 else:
5956 return main.FALSE
5957 except AssertionError:
5958 main.log.exception( "" )
5959 return main.ERROR
5960 except TypeError:
5961 main.log.exception( self.name + ": Object not as expected" )
5962 return main.ERROR
5963 except pexpect.EOF:
5964 main.log.error( self.name + ": EOF exception found" )
5965 main.log.error( self.name + ": " + self.handle.before )
5966 main.cleanAndExit()
5967 except Exception:
5968 main.log.exception( self.name + ": Uncaught exception!" )
5969 main.cleanAndExit()
5970
5971 def issuCommit( self ):
5972 """
5973 Finalizes an In-Service Software Upgrade
5974
5975 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5976 """
5977 try:
5978 cmdStr = "issu commit"
5979 handle = self.sendline( cmdStr )
5980 assert handle is not None, "Error in sendline"
5981 assert "Command not found:" not in handle, handle
5982 assert "Unsupported command:" not in handle, handle
5983 # TODO: Check the version returned by this command
5984 if "Committed version" in handle:
5985 return main.TRUE
5986 else:
5987 return main.FALSE
5988 except AssertionError:
5989 main.log.exception( "" )
5990 return main.ERROR
5991 except TypeError:
5992 main.log.exception( self.name + ": Object not as expected" )
5993 return main.ERROR
5994 except pexpect.EOF:
5995 main.log.error( self.name + ": EOF exception found" )
5996 main.log.error( self.name + ": " + self.handle.before )
5997 main.cleanAndExit()
5998 except Exception:
5999 main.log.exception( self.name + ": Uncaught exception!" )
6000 main.cleanAndExit()
6001
6002 def issuRollback( self ):
6003 """
6004 Rolls back an In-Service Software Upgrade
6005
6006 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6007 """
6008 try:
6009 cmdStr = "issu rollback"
6010 handle = self.sendline( cmdStr )
6011 assert handle is not None, "Error in sendline"
6012 assert "Command not found:" not in handle, handle
6013 assert "Unsupported command:" not in handle, handle
6014 # TODO: Check the version returned by this command
6015 if "Rolled back to version" in handle:
6016 return main.TRUE
6017 else:
6018 return main.FALSE
6019 except AssertionError:
6020 main.log.exception( "" )
6021 return main.ERROR
6022 except TypeError:
6023 main.log.exception( self.name + ": Object not as expected" )
6024 return main.ERROR
6025 except pexpect.EOF:
6026 main.log.error( self.name + ": EOF exception found" )
6027 main.log.error( self.name + ": " + self.handle.before )
6028 main.cleanAndExit()
6029 except Exception:
6030 main.log.exception( self.name + ": Uncaught exception!" )
6031 main.cleanAndExit()
6032
6033 def issuReset( self ):
6034 """
6035 Resets the In-Service Software Upgrade status after a rollback
6036
6037 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6038 """
6039 try:
6040 cmdStr = "issu reset"
6041 handle = self.sendline( cmdStr )
6042 assert handle is not None, "Error in sendline"
6043 assert "Command not found:" not in handle, handle
6044 assert "Unsupported command:" not in handle, handle
6045 # TODO: Check the version returned by this command
6046 if "Reset version" in handle:
6047 return main.TRUE
6048 else:
6049 return main.FALSE
6050 except AssertionError:
6051 main.log.exception( "" )
6052 return main.ERROR
6053 except TypeError:
6054 main.log.exception( self.name + ": Object not as expected" )
6055 return main.ERROR
6056 except pexpect.EOF:
6057 main.log.error( self.name + ": EOF exception found" )
6058 main.log.error( self.name + ": " + self.handle.before )
6059 main.cleanAndExit()
6060 except Exception:
6061 main.log.exception( self.name + ": Uncaught exception!" )
6062 main.cleanAndExit()
6063
6064 def issuStatus( self ):
6065 """
6066 Status of an In-Service Software Upgrade
6067
6068 Returns the output of the cli command or None on Error
6069 """
6070 try:
6071 cmdStr = "issu status"
6072 handle = self.sendline( cmdStr )
6073 assert handle is not None, "Error in sendline"
6074 assert "Command not found:" not in handle, handle
6075 assert "Unsupported command:" not in handle, handle
6076 return handle
6077 except AssertionError:
6078 main.log.exception( "" )
6079 return None
6080 except TypeError:
6081 main.log.exception( self.name + ": Object not as expected" )
6082 return None
6083 except pexpect.EOF:
6084 main.log.error( self.name + ": EOF exception found" )
6085 main.log.error( self.name + ": " + self.handle.before )
6086 main.cleanAndExit()
6087 except Exception:
6088 main.log.exception( self.name + ": Uncaught exception!" )
6089 main.cleanAndExit()
6090
6091 def issuVersion( self ):
6092 """
6093 Get the version of an In-Service Software Upgrade
6094
6095 Returns the output of the cli command or None on Error
6096 """
6097 try:
6098 cmdStr = "issu version"
6099 handle = self.sendline( cmdStr )
6100 assert handle is not None, "Error in sendline"
6101 assert "Command not found:" not in handle, handle
6102 assert "Unsupported command:" not in handle, handle
6103 return handle
6104 except AssertionError:
6105 main.log.exception( "" )
6106 return None
6107 except TypeError:
6108 main.log.exception( self.name + ": Object not as expected" )
6109 return None
6110 except pexpect.EOF:
6111 main.log.error( self.name + ": EOF exception found" )
6112 main.log.error( self.name + ": " + self.handle.before )
6113 main.cleanAndExit()
6114 except Exception:
6115 main.log.exception( self.name + ": Uncaught exception!" )
6116 main.cleanAndExit()