blob: 11389ca2fe68be7b8393e08ef53ec9a2646a7cb8 [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
steven308015f34c842019-01-17 11:31:45 +0800198 elif i == 2: # Timeout
Jon Hall61282e32015-03-19 11:34:11 -0700199 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
Jon Hall0e240372018-05-02 11:21:57 -0700463 def clearBuffer( self, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800464 """
Jon Hall0e240372018-05-02 11:21:57 -0700465 Test cli connection and clear any left over output in the buffer
466 Optional Arguments:
467 debug - Defaults to False. If True, will enable debug logging.
468 timeout - Defaults to 10. Amount of time in seconds for a command to return
469 before a timeout.
470 noExit - Defaults to False. If True, will not exit TestON in the event of a
kelvin8ec71442015-01-15 16:57:00 -0800471 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400472 try:
Jon Halla495f562016-05-16 18:03:26 -0700473 # Try to reconnect if disconnected from cli
474 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700475 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ] )
Jon Hall0e240372018-05-02 11:21:57 -0700476 response = self.handle.before
Jon Halla495f562016-05-16 18:03:26 -0700477 if i == 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700478 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700479 if self.onosIp:
480 main.log.warn( "Trying to reconnect " + self.onosIp )
481 reconnectResult = self.startOnosCli( self.onosIp )
482 if reconnectResult:
483 main.log.info( self.name + ": onos cli session reconnected." )
484 else:
485 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700486 if noExit:
487 return None
488 else:
Devin Lim44075962017-08-11 10:56:37 -0700489 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700490 else:
Devin Lim44075962017-08-11 10:56:37 -0700491 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700492 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700493 main.log.warn( "Timeout when testing cli responsiveness" )
494 main.log.debug( self.handle.before )
495 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700496 self.handle.expect( "onos>" )
497
Jon Hall0e240372018-05-02 11:21:57 -0700498 response += self.handle.before
Jon Hall14a03b52016-05-11 12:07:30 -0700499 if debug:
Jon Hall0e240372018-05-02 11:21:57 -0700500 main.log.debug( self.name + ": Raw output from sending ''" )
501 main.log.debug( self.name + ": " + repr( response ) )
502 except pexpect.TIMEOUT:
503 main.log.error( self.name + ": ONOS timeout" )
504 main.log.debug( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700505 self.handle.send( "\x03" )
506 self.handle.expect( "onos>" )
Jon Hall0e240372018-05-02 11:21:57 -0700507 return None
508 except pexpect.EOF:
509 main.log.error( self.name + ": EOF exception found" )
510 main.log.error( self.name + ": " + self.handle.before )
511 if noExit:
512 return None
513 else:
514 main.cleanAndExit()
515 except Exception:
516 main.log.exception( self.name + ": Uncaught exception!" )
517 if noExit:
518 return None
519 else:
520 main.cleanAndExit()
521
522 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
523 """
524 A wrapper around pexpect's sendline/expect. Will return all the output from a given command
525
526 Required Arguments:
527 cmdStr - String to send to the pexpect session
528
529 Optional Arguments:
530 showResponse - Defaults to False. If True will log the response.
531 debug - Defaults to False. If True, will enable debug logging.
532 timeout - Defaults to 10. Amount of time in seconds for a command to return
533 before a timeout.
534 noExit - Defaults to False. If True, will not exit TestON in the event of a
535 closed channel, but instead return None
536
537 Warning: There are no sanity checking to commands sent using this method.
538
539 """
540 try:
541 # Try to reconnect if disconnected from cli
542 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
543 if debug:
544 # NOTE: This adds an average of .4 seconds per call
Jon Hall14a03b52016-05-11 12:07:30 -0700545 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700546 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800547 self.handle.sendline( cmdStr )
Jon Hall3e6edb32018-08-21 16:20:30 -0700548 self.handle.expect( "onos>", timeout )
Jon Hall63604932015-02-26 17:09:50 -0800549 response = self.handle.before
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000550 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800551 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700552 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700553 main.log.debug( self.name + ": Raw output" )
554 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700555
556 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800557 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800558 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700559 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700560 main.log.debug( self.name + ": ansiEscape output" )
561 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700562
kelvin-onlabfb521662015-02-27 09:52:40 -0800563 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000564 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700565 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700566 main.log.debug( self.name + ": Removed extra returns " +
567 "from output" )
568 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700569
570 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800571 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700572 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700573 main.log.debug( self.name + ": parsed and stripped output" )
574 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700575
Jon Hall63604932015-02-26 17:09:50 -0800576 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700577 output = response.split( cmdStr.strip(), 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700578 if output:
579 if debug:
580 main.log.debug( self.name + ": split output" )
581 for r in output:
582 main.log.debug( self.name + ": " + repr( r ) )
583 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800584 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800585 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700586 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800587 return output
GlennRCed771242016-01-13 17:02:47 -0800588 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700589 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800590 if debug:
591 main.log.debug( self.handle.before )
You Wangb0f35862019-02-04 12:05:40 -0800592 self.exitFromCmd( self.karafPrompt, 100 )
GlennRCed771242016-01-13 17:02:47 -0800593 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700594 except IndexError:
595 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700596 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700597 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800598 except TypeError:
599 main.log.exception( self.name + ": Object not as expected" )
600 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400601 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800602 main.log.error( self.name + ": EOF exception found" )
603 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700604 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700605 return None
606 else:
Devin Lim44075962017-08-11 10:56:37 -0700607 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800608 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800609 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700610 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700611 return None
612 else:
Devin Lim44075962017-08-11 10:56:37 -0700613 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400614
kelvin8ec71442015-01-15 16:57:00 -0800615 # IMPORTANT NOTE:
616 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800617 # the cli command changing 'a:b' with 'aB'.
618 # Ex ) onos:topology > onosTopology
619 # onos:links > onosLinks
620 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800621
kelvin-onlabd3b64892015-01-20 13:26:24 -0800622 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800623 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400624 Adds a new cluster node by ID and address information.
625 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800626 * nodeId
627 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400628 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800629 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800630 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400631 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800632 cmdStr = "add-node " + str( nodeId ) + " " +\
633 str( ONOSIp ) + " " + str( tcpPort )
634 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700635 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800636 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800637 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700638 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800639 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800640 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400641 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800642 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400643 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800644 except AssertionError:
645 main.log.exception( "" )
646 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800647 except TypeError:
648 main.log.exception( self.name + ": Object not as expected" )
649 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400650 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800651 main.log.error( self.name + ": EOF exception found" )
652 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700653 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800654 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800655 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700656 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400657
kelvin-onlabd3b64892015-01-20 13:26:24 -0800658 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800659 """
andrewonlab86dc3082014-10-13 18:18:38 -0400660 Removes a cluster by ID
661 Issues command: 'remove-node [<node-id>]'
662 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800663 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800664 """
andrewonlab86dc3082014-10-13 18:18:38 -0400665 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400666
kelvin-onlabd3b64892015-01-20 13:26:24 -0800667 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700668 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700669 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800670 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700671 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700672 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700673 main.log.error( handle )
674 return main.FALSE
675 else:
676 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800677 except AssertionError:
678 main.log.exception( "" )
679 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800680 except TypeError:
681 main.log.exception( self.name + ": Object not as expected" )
682 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400683 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800684 main.log.error( self.name + ": EOF exception found" )
685 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700686 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800687 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800688 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700689 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400690
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700691 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800692 """
andrewonlab7c211572014-10-15 16:45:20 -0400693 List the nodes currently visible
694 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700695 Optional argument:
696 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800697 """
andrewonlab7c211572014-10-15 16:45:20 -0400698 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700699 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700700 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700701 cmdStr += " -j"
702 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700703 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800704 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700705 return output
Jon Hallc6793552016-01-19 14:18:37 -0800706 except AssertionError:
707 main.log.exception( "" )
708 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800709 except TypeError:
710 main.log.exception( self.name + ": Object not as expected" )
711 return None
andrewonlab7c211572014-10-15 16:45:20 -0400712 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800713 main.log.error( self.name + ": EOF exception found" )
714 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700715 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800716 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800717 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700718 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400719
kelvin8ec71442015-01-15 16:57:00 -0800720 def topology( self ):
721 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700722 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700723 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700724 Return:
725 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800726 """
andrewonlab95ce8322014-10-13 14:12:04 -0400727 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700728 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800729 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800730 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800731 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700732 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400733 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800734 except AssertionError:
735 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800736 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800737 except TypeError:
738 main.log.exception( self.name + ": Object not as expected" )
739 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400740 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800741 main.log.error( self.name + ": EOF exception found" )
742 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700743 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800744 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800745 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700746 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800747
jenkins7ead5a82015-03-13 10:28:21 -0700748 def deviceRemove( self, deviceId ):
749 """
750 Removes particular device from storage
751
752 TODO: refactor this function
753 """
754 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700755 cmdStr = "device-remove " + str( deviceId )
756 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800757 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800758 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700759 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700760 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700761 main.log.error( handle )
762 return main.FALSE
763 else:
764 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800765 except AssertionError:
766 main.log.exception( "" )
767 return None
jenkins7ead5a82015-03-13 10:28:21 -0700768 except TypeError:
769 main.log.exception( self.name + ": Object not as expected" )
770 return None
771 except pexpect.EOF:
772 main.log.error( self.name + ": EOF exception found" )
773 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700774 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700775 except Exception:
776 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700777 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700778
You Wang3b9689a2018-08-30 12:24:00 -0700779 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800780 """
Jon Hall7b02d952014-10-17 20:14:54 -0400781 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400782 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800783 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800784 """
andrewonlab86dc3082014-10-13 18:18:38 -0400785 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700786 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800787 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700788 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700789 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800790 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800791 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700792 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800793 except AssertionError:
794 main.log.exception( "" )
795 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800796 except TypeError:
797 main.log.exception( self.name + ": Object not as expected" )
798 return None
andrewonlab7c211572014-10-15 16:45:20 -0400799 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800800 main.log.error( self.name + ": EOF exception found" )
801 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700802 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800803 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800804 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700805 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400806
kelvin-onlabd3b64892015-01-20 13:26:24 -0800807 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800808 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800809 This balances the devices across all controllers
810 by issuing command: 'onos> onos:balance-masters'
811 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800812 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800813 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800814 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700815 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800816 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800817 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700818 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700819 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700820 main.log.error( handle )
821 return main.FALSE
822 else:
823 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800824 except AssertionError:
825 main.log.exception( "" )
826 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800827 except TypeError:
828 main.log.exception( self.name + ": Object not as expected" )
829 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800830 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800831 main.log.error( self.name + ": EOF exception found" )
832 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700833 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800834 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800835 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700836 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800837
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000838 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700839 """
840 Returns the output of the masters command.
841 Optional argument:
842 * jsonFormat - boolean indicating if you want output in json
843 """
844 try:
845 cmdStr = "onos:masters"
846 if jsonFormat:
847 cmdStr += " -j"
848 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700849 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800850 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700851 return output
Jon Hallc6793552016-01-19 14:18:37 -0800852 except AssertionError:
853 main.log.exception( "" )
854 return None
acsmars24950022015-07-30 18:00:43 -0700855 except TypeError:
856 main.log.exception( self.name + ": Object not as expected" )
857 return None
858 except pexpect.EOF:
859 main.log.error( self.name + ": EOF exception found" )
860 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700861 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700862 except Exception:
863 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700864 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700865
Jon Hallc6793552016-01-19 14:18:37 -0800866 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700867 """
868 Uses the master command to check that the devices' leadership
869 is evenly divided
870
871 Dependencies: checkMasters() and summary()
872
Jon Hall6509dbf2016-06-21 17:01:17 -0700873 Returns main.TRUE if the devices are balanced
874 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700875 Exits on Exception
876 Returns None on TypeError
877 """
878 try:
Jon Hallc6793552016-01-19 14:18:37 -0800879 summaryOutput = self.summary()
880 totalDevices = json.loads( summaryOutput )[ "devices" ]
881 except ( TypeError, ValueError ):
882 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
883 return None
884 try:
acsmars24950022015-07-30 18:00:43 -0700885 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800886 mastersOutput = self.checkMasters()
887 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700888 first = masters[ 0 ][ "size" ]
889 for master in masters:
890 totalOwnedDevices += master[ "size" ]
891 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
892 main.log.error( "Mastership not balanced" )
893 main.log.info( "\n" + self.checkMasters( False ) )
894 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700895 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700896 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700897 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800898 except ( TypeError, ValueError ):
899 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700900 return None
901 except pexpect.EOF:
902 main.log.error( self.name + ": EOF exception found" )
903 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700904 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700905 except Exception:
906 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700907 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700908
YPZhangfebf7302016-05-24 16:45:56 -0700909 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800910 """
Jon Halle8217482014-10-17 13:49:14 -0400911 Lists all core links
912 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800913 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800914 """
Jon Halle8217482014-10-17 13:49:14 -0400915 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700916 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800917 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700918 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700919 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800920 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800921 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700922 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800923 except AssertionError:
924 main.log.exception( "" )
925 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800926 except TypeError:
927 main.log.exception( self.name + ": Object not as expected" )
928 return None
Jon Halle8217482014-10-17 13:49:14 -0400929 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800930 main.log.error( self.name + ": EOF exception found" )
931 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700932 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800933 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800934 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700935 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400936
You Wang3b9689a2018-08-30 12:24:00 -0700937 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800938 """
Jon Halle8217482014-10-17 13:49:14 -0400939 Lists all ports
940 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800941 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800942 """
Jon Halle8217482014-10-17 13:49:14 -0400943 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700944 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800945 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700946 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700947 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800948 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800949 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700950 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800951 except AssertionError:
952 main.log.exception( "" )
953 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800954 except TypeError:
955 main.log.exception( self.name + ": Object not as expected" )
956 return None
Jon Halle8217482014-10-17 13:49:14 -0400957 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800958 main.log.error( self.name + ": EOF exception found" )
959 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700960 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800961 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800962 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700963 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400964
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800966 """
Jon Hall983a1702014-10-28 18:44:22 -0400967 Lists all devices and the controllers with roles assigned to them
968 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800969 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800970 """
andrewonlab7c211572014-10-15 16:45:20 -0400971 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700972 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800973 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700974 cmdStr += " -j"
975 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800976 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800977 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700978 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800979 except AssertionError:
980 main.log.exception( "" )
981 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800982 except TypeError:
983 main.log.exception( self.name + ": Object not as expected" )
984 return None
Jon Hall983a1702014-10-28 18:44:22 -0400985 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800986 main.log.error( self.name + ": EOF exception found" )
987 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700988 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800989 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800990 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700991 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -0400992
kelvin-onlabd3b64892015-01-20 13:26:24 -0800993 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800994 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800995 Given the a string containing the json representation of the "roles"
996 cli command and a partial or whole device id, returns a json object
997 containing the roles output for the first device whose id contains
998 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400999
1000 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001001 A dict of the role assignments for the given device or
1002 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001003 """
Jon Hall983a1702014-10-28 18:44:22 -04001004 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001005 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001006 return None
1007 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001008 rawRoles = self.roles()
1009 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001010 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001011 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001012 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001013 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001014 return device
1015 return None
Jon Hallc6793552016-01-19 14:18:37 -08001016 except ( TypeError, ValueError ):
1017 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001018 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001019 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001020 main.log.error( self.name + ": EOF exception found" )
1021 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001022 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001023 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001024 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001025 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001026
kelvin-onlabd3b64892015-01-20 13:26:24 -08001027 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001028 """
Jon Hall94fd0472014-12-08 11:52:42 -08001029 Iterates through each device and checks if there is a master assigned
1030 Returns: main.TRUE if each device has a master
1031 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001032 """
Jon Hall94fd0472014-12-08 11:52:42 -08001033 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001034 rawRoles = self.roles()
1035 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001036 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001037 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001038 # print device
1039 if device[ 'master' ] == "none":
1040 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001041 return main.FALSE
1042 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001043 except ( TypeError, ValueError ):
1044 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001045 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001046 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001047 main.log.error( self.name + ": EOF exception found" )
1048 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001049 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001050 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001051 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001052 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001053
kelvin-onlabd3b64892015-01-20 13:26:24 -08001054 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001055 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001056 Returns string of paths, and the cost.
1057 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001058 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001059 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001060 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1061 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001062 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001063 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001064 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001065 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001066 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001067 else:
kelvin8ec71442015-01-15 16:57:00 -08001068 path = handle.split( ";" )[ 0 ]
1069 cost = handle.split( ";" )[ 1 ]
1070 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001071 except AssertionError:
1072 main.log.exception( "" )
1073 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001074 except TypeError:
1075 main.log.exception( self.name + ": Object not as expected" )
1076 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001077 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001078 main.log.error( self.name + ": EOF exception found" )
1079 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001080 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001081 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001082 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001083 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001084
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001086 """
Jon Hallffb386d2014-11-21 13:43:38 -08001087 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001088 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001089 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001090 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001091 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001092 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001094 cmdStr += " -j"
1095 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001096 if handle:
1097 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001098 # TODO: Maybe make this less hardcoded
1099 # ConsistentMap Exceptions
1100 assert "org.onosproject.store.service" not in handle
1101 # Node not leader
1102 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001103 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001104 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001105 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001106 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001107 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001108 except TypeError:
1109 main.log.exception( self.name + ": Object not as expected" )
1110 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001111 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001112 main.log.error( self.name + ": EOF exception found" )
1113 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001114 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001115 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001116 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001117 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001118
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001120 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001121 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001122
Jon Hallefbd9792015-03-05 16:11:36 -08001123 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001124 partial mac address
1125
Jon Hall42db6dc2014-10-24 19:03:48 -04001126 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001127 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001128 try:
kelvin8ec71442015-01-15 16:57:00 -08001129 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001130 return None
1131 else:
1132 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 rawHosts = self.hosts()
1134 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001135 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001137 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001138 if not host:
1139 pass
1140 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001141 return host
1142 return None
Jon Hallc6793552016-01-19 14:18:37 -08001143 except ( TypeError, ValueError ):
1144 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001145 return None
Jon Hall42db6dc2014-10-24 19:03:48 -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()
Jon Hall42db6dc2014-10-24 19:03:48 -04001153
kelvin-onlabd3b64892015-01-20 13:26:24 -08001154 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001155 """
1156 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001157 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001158
andrewonlab3f0a4af2014-10-17 12:25:14 -04001159 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001160 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001161 IMPORTANT:
1162 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001163 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001164 Furthermore, it assumes that value of VLAN is '-1'
1165 Description:
kelvin8ec71442015-01-15 16:57:00 -08001166 Converts mininet hosts ( h1, h2, h3... ) into
1167 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1168 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001169 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001170 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001171
kelvin-onlabd3b64892015-01-20 13:26:24 -08001172 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001173 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001174 hostHex = hex( int( host ) ).zfill( 12 )
1175 hostHex = str( hostHex ).replace( 'x', '0' )
1176 i = iter( str( hostHex ) )
1177 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1178 hostHex = hostHex + "/-1"
1179 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001180
kelvin-onlabd3b64892015-01-20 13:26:24 -08001181 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001182
Jon Halld4d4b372015-01-28 16:02:41 -08001183 except TypeError:
1184 main.log.exception( self.name + ": Object not as expected" )
1185 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001186 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001187 main.log.error( self.name + ": EOF exception found" )
1188 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001189 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001190 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001191 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001192 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001193
You Wangbc898b82018-05-03 16:22:34 -07001194 def verifyHostLocation( self, hostIp, location ):
1195 """
1196 Description:
1197 Verify the host given is discovered in all locations expected
1198 Required:
1199 hostIp: IP address of the host
1200 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1201 Could be a string or list
1202 Returns:
1203 main.TRUE if host is discovered on all locations provided
1204 main.FALSE otherwise
1205 """
1206 import json
1207 locations = [ location ] if isinstance( location, str ) else location
1208 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1209 try:
1210 hosts = self.hosts()
1211 hosts = json.loads( hosts )
1212 targetHost = None
1213 for host in hosts:
1214 if hostIp in host[ "ipAddresses" ]:
1215 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001216 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001217 result = main.TRUE
1218 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1219 for loc in locations:
1220 discovered = False
1221 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001222 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1223 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001224 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001225 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001226 break
1227 if discovered:
1228 locationsDiscovered.remove( locDiscovered )
1229 else:
1230 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1231 result = main.FALSE
1232 if locationsDiscovered:
1233 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1234 result = main.FALSE
1235 return result
1236 except KeyError:
1237 main.log.exception( self.name + ": host data not as expected: " + hosts )
1238 return None
1239 except pexpect.EOF:
1240 main.log.error( self.name + ": EOF exception found" )
1241 main.log.error( self.name + ": " + self.handle.before )
1242 main.cleanAndExit()
1243 except Exception:
1244 main.log.exception( self.name + ": Uncaught exception" )
1245 return None
1246
You Wang53dba1e2018-02-02 17:45:44 -08001247 def verifyHostIp( self, hostList=[], prefix="" ):
1248 """
1249 Description:
1250 Verify that all hosts have IP address assigned to them
1251 Optional:
1252 hostList: If specified, verifications only happen to the hosts
1253 in hostList
1254 prefix: at least one of the ip address assigned to the host
1255 needs to have the specified prefix
1256 Returns:
1257 main.TRUE if all hosts have specific IP address assigned;
1258 main.FALSE otherwise
1259 """
1260 import json
1261 try:
1262 hosts = self.hosts()
1263 hosts = json.loads( hosts )
1264 if not hostList:
1265 hostList = [ host[ "id" ] for host in hosts ]
1266 for host in hosts:
1267 hostId = host[ "id" ]
1268 if hostId not in hostList:
1269 continue
1270 ipList = host[ "ipAddresses" ]
1271 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1272 if not ipList:
1273 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1274 else:
1275 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1276 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1277 else:
1278 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1279 hostList.remove( hostId )
1280 if hostList:
1281 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1282 return main.FALSE
1283 else:
1284 return main.TRUE
1285 except KeyError:
1286 main.log.exception( self.name + ": host data not as expected: " + hosts )
1287 return None
1288 except pexpect.EOF:
1289 main.log.error( self.name + ": EOF exception found" )
1290 main.log.error( self.name + ": " + self.handle.before )
1291 main.cleanAndExit()
1292 except Exception:
1293 main.log.exception( self.name + ": Uncaught exception" )
1294 return None
1295
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001296 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001297 """
andrewonlabe6745342014-10-17 14:29:13 -04001298 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001299 * hostIdOne: ONOS host id for host1
1300 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001301 Optional:
1302 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001303 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001304 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001305 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001306 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001307 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001308 Returns:
1309 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001310 """
andrewonlabe6745342014-10-17 14:29:13 -04001311 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001312 cmdStr = "add-host-intent "
1313 if vlanId:
1314 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001315 if setVlan:
1316 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001317 if encap:
1318 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001319 if bandwidth:
1320 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001321 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001322 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001323 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001324 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001325 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001326 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001327 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001328 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001329 else:
1330 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001331 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001332 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001333 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001334 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001335 else:
1336 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001337 main.log.debug( "Response from ONOS was: " +
1338 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001339 return None
Jon Hallc6793552016-01-19 14:18:37 -08001340 except AssertionError:
1341 main.log.exception( "" )
1342 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001343 except TypeError:
1344 main.log.exception( self.name + ": Object not as expected" )
1345 return None
andrewonlabe6745342014-10-17 14:29:13 -04001346 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001347 main.log.error( self.name + ": EOF exception found" )
1348 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001349 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001350 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001351 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001352 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001353
kelvin-onlabd3b64892015-01-20 13:26:24 -08001354 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001355 """
andrewonlab7b31d232014-10-24 13:31:47 -04001356 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001357 * ingressDevice: device id of ingress device
1358 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001359 Optional:
1360 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001361 Description:
1362 Adds an optical intent by specifying an ingress and egress device
1363 Returns:
1364 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001365 """
andrewonlab7b31d232014-10-24 13:31:47 -04001366 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001367 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1368 " " + str( egressDevice )
1369 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001370 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001371 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001372 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001373 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001374 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001375 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001376 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001377 main.log.info( "Optical intent installed between " +
1378 str( ingressDevice ) + " and " +
1379 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001380 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001381 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001382 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001383 else:
1384 main.log.error( "Error, intent ID not found" )
1385 return None
Jon Hallc6793552016-01-19 14:18:37 -08001386 except AssertionError:
1387 main.log.exception( "" )
1388 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001389 except TypeError:
1390 main.log.exception( self.name + ": Object not as expected" )
1391 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001392 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001393 main.log.error( self.name + ": EOF exception found" )
1394 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001395 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001396 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001397 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001398 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001399
kelvin-onlabd3b64892015-01-20 13:26:24 -08001400 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001401 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001402 ingressDevice,
1403 egressDevice,
1404 portIngress="",
1405 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001406 ethType="",
1407 ethSrc="",
1408 ethDst="",
1409 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001410 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001411 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001412 ipProto="",
1413 ipSrc="",
1414 ipDst="",
1415 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001416 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001417 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001418 setVlan="",
1419 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001420 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001421 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001422 * ingressDevice: device id of ingress device
1423 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001424 Optional:
1425 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001426 * ethSrc: specify ethSrc ( i.e. src mac addr )
1427 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001428 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001429 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001430 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001431 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001432 * ipSrc: specify ip source address
1433 * ipDst: specify ip destination address
1434 * tcpSrc: specify tcp source port
1435 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001436 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001437 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001438 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001439 Description:
kelvin8ec71442015-01-15 16:57:00 -08001440 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001441 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001442 Returns:
1443 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001444
Jon Halle3f39ff2015-01-13 11:50:53 -08001445 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001446 options developers provide for point-to-point
1447 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001448 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001449 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001450 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001451
Jeremy Songsterff553672016-05-12 17:06:23 -07001452 if ethType:
1453 cmd += " --ethType " + str( ethType )
1454 if ethSrc:
1455 cmd += " --ethSrc " + str( ethSrc )
1456 if ethDst:
1457 cmd += " --ethDst " + str( ethDst )
1458 if bandwidth:
1459 cmd += " --bandwidth " + str( bandwidth )
1460 if lambdaAlloc:
1461 cmd += " --lambda "
1462 if ipProto:
1463 cmd += " --ipProto " + str( ipProto )
1464 if ipSrc:
1465 cmd += " --ipSrc " + str( ipSrc )
1466 if ipDst:
1467 cmd += " --ipDst " + str( ipDst )
1468 if tcpSrc:
1469 cmd += " --tcpSrc " + str( tcpSrc )
1470 if tcpDst:
1471 cmd += " --tcpDst " + str( tcpDst )
1472 if vlanId:
1473 cmd += " -v " + str( vlanId )
1474 if setVlan:
1475 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001476 if encap:
1477 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001478 if protected:
1479 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001480
kelvin8ec71442015-01-15 16:57:00 -08001481 # Check whether the user appended the port
1482 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001483 if "/" in ingressDevice:
1484 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001485 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001486 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001487 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001488 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001489 # Would it make sense to throw an exception and exit
1490 # the test?
1491 return None
andrewonlab36af3822014-11-18 17:48:18 -05001492
kelvin8ec71442015-01-15 16:57:00 -08001493 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001494 str( ingressDevice ) + "/" +\
1495 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001496
kelvin-onlabd3b64892015-01-20 13:26:24 -08001497 if "/" in egressDevice:
1498 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001499 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001500 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001501 main.log.error( "You must specify the egress port" )
1502 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001503
kelvin8ec71442015-01-15 16:57:00 -08001504 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001505 str( egressDevice ) + "/" +\
1506 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001507
kelvin-onlab898a6c62015-01-16 14:13:53 -08001508 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001509 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001510 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001511 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001512 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001513 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001514 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001515 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001516 # TODO: print out all the options in this message?
1517 main.log.info( "Point-to-point intent installed between " +
1518 str( ingressDevice ) + " and " +
1519 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001520 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001521 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001522 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001523 else:
1524 main.log.error( "Error, intent ID not found" )
1525 return None
Jon Hallc6793552016-01-19 14:18:37 -08001526 except AssertionError:
1527 main.log.exception( "" )
1528 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001529 except TypeError:
1530 main.log.exception( self.name + ": Object not as expected" )
1531 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001532 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001533 main.log.error( self.name + ": EOF exception found" )
1534 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001535 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001536 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001537 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001538 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001539
kelvin-onlabd3b64892015-01-20 13:26:24 -08001540 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001541 self,
shahshreyac2f97072015-03-19 17:04:29 -07001542 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001543 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001544 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001545 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001546 ethType="",
1547 ethSrc="",
1548 ethDst="",
1549 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001550 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001551 ipProto="",
1552 ipSrc="",
1553 ipDst="",
1554 tcpSrc="",
1555 tcpDst="",
1556 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001557 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001558 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001559 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001560 partial=False,
1561 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001562 """
shahshreyad0c80432014-12-04 16:56:05 -08001563 Note:
shahshreya70622b12015-03-19 17:19:00 -07001564 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001565 is same. That is, all ingress devices include port numbers
1566 with a "/" or all ingress devices could specify device
1567 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001568 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001569 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001570 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001571 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001572 Optional:
1573 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001574 * ethSrc: specify ethSrc ( i.e. src mac addr )
1575 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001576 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001577 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001578 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001579 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001580 * ipSrc: specify ip source address
1581 * ipDst: specify ip destination address
1582 * tcpSrc: specify tcp source port
1583 * tcpDst: specify tcp destination port
1584 * setEthSrc: action to Rewrite Source MAC Address
1585 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001586 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001587 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001588 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001589 Description:
kelvin8ec71442015-01-15 16:57:00 -08001590 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001591 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001592 Returns:
1593 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001594
Jon Halle3f39ff2015-01-13 11:50:53 -08001595 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001596 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001597 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001598 """
shahshreyad0c80432014-12-04 16:56:05 -08001599 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001600 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001601
Jeremy Songsterff553672016-05-12 17:06:23 -07001602 if ethType:
1603 cmd += " --ethType " + str( ethType )
1604 if ethSrc:
1605 cmd += " --ethSrc " + str( ethSrc )
1606 if ethDst:
1607 cmd += " --ethDst " + str( ethDst )
1608 if bandwidth:
1609 cmd += " --bandwidth " + str( bandwidth )
1610 if lambdaAlloc:
1611 cmd += " --lambda "
1612 if ipProto:
1613 cmd += " --ipProto " + str( ipProto )
1614 if ipSrc:
1615 cmd += " --ipSrc " + str( ipSrc )
1616 if ipDst:
1617 cmd += " --ipDst " + str( ipDst )
1618 if tcpSrc:
1619 cmd += " --tcpSrc " + str( tcpSrc )
1620 if tcpDst:
1621 cmd += " --tcpDst " + str( tcpDst )
1622 if setEthSrc:
1623 cmd += " --setEthSrc " + str( setEthSrc )
1624 if setEthDst:
1625 cmd += " --setEthDst " + str( setEthDst )
1626 if vlanId:
1627 cmd += " -v " + str( vlanId )
1628 if setVlan:
1629 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001630 if partial:
1631 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001632 if encap:
1633 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001634
kelvin8ec71442015-01-15 16:57:00 -08001635 # Check whether the user appended the port
1636 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001637
1638 if portIngressList is None:
1639 for ingressDevice in ingressDeviceList:
1640 if "/" in ingressDevice:
1641 cmd += " " + str( ingressDevice )
1642 else:
1643 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001644 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001645 # TODO: perhaps more meaningful return
1646 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001647 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001648 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001649 for ingressDevice, portIngress in zip( ingressDeviceList,
1650 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001651 cmd += " " + \
1652 str( ingressDevice ) + "/" +\
1653 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001654 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001655 main.log.error( "Device list and port list does not " +
1656 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001657 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001658 if "/" in egressDevice:
1659 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001660 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001661 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001662 main.log.error( "You must specify " +
1663 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001664 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001665
kelvin8ec71442015-01-15 16:57:00 -08001666 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001667 str( egressDevice ) + "/" +\
1668 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001669 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001670 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001671 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001672 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001673 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001674 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001675 "intent" )
1676 return None
shahshreyad0c80432014-12-04 16:56:05 -08001677 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001678 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001679 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001680 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001681 else:
1682 main.log.error( "Error, intent ID not found" )
1683 return None
Jon Hallc6793552016-01-19 14:18:37 -08001684 except AssertionError:
1685 main.log.exception( "" )
1686 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001687 except TypeError:
1688 main.log.exception( self.name + ": Object not as expected" )
1689 return None
1690 except pexpect.EOF:
1691 main.log.error( self.name + ": EOF exception found" )
1692 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001693 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001694 except Exception:
1695 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001696 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001697
1698 def addSinglepointToMultipointIntent(
1699 self,
1700 ingressDevice,
1701 egressDeviceList,
1702 portIngress="",
1703 portEgressList=None,
1704 ethType="",
1705 ethSrc="",
1706 ethDst="",
1707 bandwidth="",
1708 lambdaAlloc=False,
1709 ipProto="",
1710 ipSrc="",
1711 ipDst="",
1712 tcpSrc="",
1713 tcpDst="",
1714 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001715 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001716 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001717 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001718 partial=False,
1719 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001720 """
1721 Note:
1722 This function assumes the format of all egress devices
1723 is same. That is, all egress devices include port numbers
1724 with a "/" or all egress devices could specify device
1725 ids and port numbers seperately.
1726 Required:
1727 * EgressDeviceList: List of device ids of egress device
1728 ( Atleast 2 eress devices required in the list )
1729 * ingressDevice: device id of ingress device
1730 Optional:
1731 * ethType: specify ethType
1732 * ethSrc: specify ethSrc ( i.e. src mac addr )
1733 * ethDst: specify ethDst ( i.e. dst mac addr )
1734 * bandwidth: specify bandwidth capacity of link
1735 * lambdaAlloc: if True, intent will allocate lambda
1736 for the specified intent
1737 * ipProto: specify ip protocol
1738 * ipSrc: specify ip source address
1739 * ipDst: specify ip destination address
1740 * tcpSrc: specify tcp source port
1741 * tcpDst: specify tcp destination port
1742 * setEthSrc: action to Rewrite Source MAC Address
1743 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001744 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001745 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001746 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001747 Description:
1748 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1749 specifying device id's and optional fields
1750 Returns:
1751 A string of the intent id or None on error
1752
1753 NOTE: This function may change depending on the
1754 options developers provide for singlepoint-to-multipoint
1755 intent via cli
1756 """
1757 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001758 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001759
Jeremy Songsterff553672016-05-12 17:06:23 -07001760 if ethType:
1761 cmd += " --ethType " + str( ethType )
1762 if ethSrc:
1763 cmd += " --ethSrc " + str( ethSrc )
1764 if ethDst:
1765 cmd += " --ethDst " + str( ethDst )
1766 if bandwidth:
1767 cmd += " --bandwidth " + str( bandwidth )
1768 if lambdaAlloc:
1769 cmd += " --lambda "
1770 if ipProto:
1771 cmd += " --ipProto " + str( ipProto )
1772 if ipSrc:
1773 cmd += " --ipSrc " + str( ipSrc )
1774 if ipDst:
1775 cmd += " --ipDst " + str( ipDst )
1776 if tcpSrc:
1777 cmd += " --tcpSrc " + str( tcpSrc )
1778 if tcpDst:
1779 cmd += " --tcpDst " + str( tcpDst )
1780 if setEthSrc:
1781 cmd += " --setEthSrc " + str( setEthSrc )
1782 if setEthDst:
1783 cmd += " --setEthDst " + str( setEthDst )
1784 if vlanId:
1785 cmd += " -v " + str( vlanId )
1786 if setVlan:
1787 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001788 if partial:
1789 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001790 if encap:
1791 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001792
1793 # Check whether the user appended the port
1794 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001795
kelvin-onlabb9408212015-04-01 13:34:04 -07001796 if "/" in ingressDevice:
1797 cmd += " " + str( ingressDevice )
1798 else:
1799 if not portIngress:
1800 main.log.error( "You must specify " +
1801 "the Ingress port" )
1802 return main.FALSE
1803
1804 cmd += " " +\
1805 str( ingressDevice ) + "/" +\
1806 str( portIngress )
1807
1808 if portEgressList is None:
1809 for egressDevice in egressDeviceList:
1810 if "/" in egressDevice:
1811 cmd += " " + str( egressDevice )
1812 else:
1813 main.log.error( "You must specify " +
1814 "the egress port" )
1815 # TODO: perhaps more meaningful return
1816 return main.FALSE
1817 else:
1818 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001819 for egressDevice, portEgress in zip( egressDeviceList,
1820 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001821 cmd += " " + \
1822 str( egressDevice ) + "/" +\
1823 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001824 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001825 main.log.error( "Device list and port list does not " +
1826 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001827 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001828 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001829 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001830 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001831 # If error, return error message
1832 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001833 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001834 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001835 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001836 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001837 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001838 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001839 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001840 else:
1841 main.log.error( "Error, intent ID not found" )
1842 return None
Jon Hallc6793552016-01-19 14:18:37 -08001843 except AssertionError:
1844 main.log.exception( "" )
1845 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001846 except TypeError:
1847 main.log.exception( self.name + ": Object not as expected" )
1848 return None
shahshreyad0c80432014-12-04 16:56:05 -08001849 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001850 main.log.error( self.name + ": EOF exception found" )
1851 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001852 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001853 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001854 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001855 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001856
Hari Krishna9e232602015-04-13 17:29:08 -07001857 def addMplsIntent(
1858 self,
1859 ingressDevice,
1860 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001861 ingressPort="",
1862 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001863 ethType="",
1864 ethSrc="",
1865 ethDst="",
1866 bandwidth="",
1867 lambdaAlloc=False,
1868 ipProto="",
1869 ipSrc="",
1870 ipDst="",
1871 tcpSrc="",
1872 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001873 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001874 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001875 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001876 """
1877 Required:
1878 * ingressDevice: device id of ingress device
1879 * egressDevice: device id of egress device
1880 Optional:
1881 * ethType: specify ethType
1882 * ethSrc: specify ethSrc ( i.e. src mac addr )
1883 * ethDst: specify ethDst ( i.e. dst mac addr )
1884 * bandwidth: specify bandwidth capacity of link
1885 * lambdaAlloc: if True, intent will allocate lambda
1886 for the specified intent
1887 * ipProto: specify ip protocol
1888 * ipSrc: specify ip source address
1889 * ipDst: specify ip destination address
1890 * tcpSrc: specify tcp source port
1891 * tcpDst: specify tcp destination port
1892 * ingressLabel: Ingress MPLS label
1893 * egressLabel: Egress MPLS label
1894 Description:
1895 Adds MPLS intent by
1896 specifying device id's and optional fields
1897 Returns:
1898 A string of the intent id or None on error
1899
1900 NOTE: This function may change depending on the
1901 options developers provide for MPLS
1902 intent via cli
1903 """
1904 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001905 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001906
Jeremy Songsterff553672016-05-12 17:06:23 -07001907 if ethType:
1908 cmd += " --ethType " + str( ethType )
1909 if ethSrc:
1910 cmd += " --ethSrc " + str( ethSrc )
1911 if ethDst:
1912 cmd += " --ethDst " + str( ethDst )
1913 if bandwidth:
1914 cmd += " --bandwidth " + str( bandwidth )
1915 if lambdaAlloc:
1916 cmd += " --lambda "
1917 if ipProto:
1918 cmd += " --ipProto " + str( ipProto )
1919 if ipSrc:
1920 cmd += " --ipSrc " + str( ipSrc )
1921 if ipDst:
1922 cmd += " --ipDst " + str( ipDst )
1923 if tcpSrc:
1924 cmd += " --tcpSrc " + str( tcpSrc )
1925 if tcpDst:
1926 cmd += " --tcpDst " + str( tcpDst )
1927 if ingressLabel:
1928 cmd += " --ingressLabel " + str( ingressLabel )
1929 if egressLabel:
1930 cmd += " --egressLabel " + str( egressLabel )
1931 if priority:
1932 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001933
1934 # Check whether the user appended the port
1935 # or provided it as an input
1936 if "/" in ingressDevice:
1937 cmd += " " + str( ingressDevice )
1938 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001939 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001940 main.log.error( "You must specify the ingress port" )
1941 return None
1942
1943 cmd += " " + \
1944 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001945 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001946
1947 if "/" in egressDevice:
1948 cmd += " " + str( egressDevice )
1949 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001950 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001951 main.log.error( "You must specify the egress port" )
1952 return None
1953
1954 cmd += " " +\
1955 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001956 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001957
1958 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001959 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001960 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001961 # If error, return error message
1962 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001963 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07001964 return None
1965 else:
1966 # TODO: print out all the options in this message?
1967 main.log.info( "MPLS intent installed between " +
1968 str( ingressDevice ) + " and " +
1969 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001970 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07001971 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001972 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07001973 else:
1974 main.log.error( "Error, intent ID not found" )
1975 return None
Jon Hallc6793552016-01-19 14:18:37 -08001976 except AssertionError:
1977 main.log.exception( "" )
1978 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001979 except TypeError:
1980 main.log.exception( self.name + ": Object not as expected" )
1981 return None
1982 except pexpect.EOF:
1983 main.log.error( self.name + ": EOF exception found" )
1984 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001985 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001986 except Exception:
1987 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001988 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001989
Jon Hallefbd9792015-03-05 16:11:36 -08001990 def removeIntent( self, intentId, app='org.onosproject.cli',
1991 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001992 """
shahshreya1c818fc2015-02-26 13:44:08 -08001993 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001994 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001995 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001996 -p or --purge: Purge the intent from the store after removal
1997
Jon Halle3f39ff2015-01-13 11:50:53 -08001998 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001999 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002000 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002001 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002002 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002003 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002004 if purge:
2005 cmdStr += " -p"
2006 if sync:
2007 cmdStr += " -s"
2008
2009 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002010 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002011 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002012 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002013 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002014 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002015 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002016 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002017 # TODO: Should this be main.TRUE
2018 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002019 except AssertionError:
2020 main.log.exception( "" )
2021 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002022 except TypeError:
2023 main.log.exception( self.name + ": Object not as expected" )
2024 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002025 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002026 main.log.error( self.name + ": EOF exception found" )
2027 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002028 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002029 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002030 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002031 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002032
YPZhangfebf7302016-05-24 16:45:56 -07002033 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002034 """
2035 Description:
2036 Remove all the intents
2037 Optional args:-
2038 -s or --sync: Waits for the removal before returning
2039 -p or --purge: Purge the intent from the store after removal
2040 Returns:
2041 Returns main.TRUE if all intents are removed, otherwise returns
2042 main.FALSE; Returns None for exception
2043 """
2044 try:
2045 cmdStr = "remove-intent"
2046 if purge:
2047 cmdStr += " -p"
2048 if sync:
2049 cmdStr += " -s"
2050
2051 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002052 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002053 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002054 assert "Command not found:" not in handle, handle
2055 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002056 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002057 return main.FALSE
2058 else:
2059 return main.TRUE
2060 except AssertionError:
2061 main.log.exception( "" )
2062 return None
2063 except TypeError:
2064 main.log.exception( self.name + ": Object not as expected" )
2065 return None
2066 except pexpect.EOF:
2067 main.log.error( self.name + ": EOF exception found" )
2068 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002069 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002070 except Exception:
2071 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002072 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002073
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002074 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002075 """
2076 Purges all WITHDRAWN Intents
2077 """
2078 try:
2079 cmdStr = "purge-intents"
2080 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002081 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002082 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002083 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002084 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002085 return main.FALSE
2086 else:
2087 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002088 except AssertionError:
2089 main.log.exception( "" )
2090 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002091 except TypeError:
2092 main.log.exception( self.name + ": Object not as expected" )
2093 return None
2094 except pexpect.EOF:
2095 main.log.error( self.name + ": EOF exception found" )
2096 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002097 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002098 except Exception:
2099 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002100 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002101
Devin Lime6fe3c42017-10-18 16:28:40 -07002102 def wipeout( self ):
2103 """
2104 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2105 """
2106 try:
2107 cmdStr = "wipe-out please"
2108 handle = self.sendline( cmdStr, timeout=60 )
2109 assert handle is not None, "Error in sendline"
2110 assert "Command not found:" not in handle, handle
2111 return main.TRUE
2112 except AssertionError:
2113 main.log.exception( "" )
2114 return None
2115 except TypeError:
2116 main.log.exception( self.name + ": Object not as expected" )
2117 return None
2118 except pexpect.EOF:
2119 main.log.error( self.name + ": EOF exception found" )
2120 main.log.error( self.name + ": " + self.handle.before )
2121 main.cleanAndExit()
2122 except Exception:
2123 main.log.exception( self.name + ": Uncaught exception!" )
2124 main.cleanAndExit()
2125
kelvin-onlabd3b64892015-01-20 13:26:24 -08002126 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002127 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002128 NOTE: This method should be used after installing application:
2129 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002130 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002131 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002132 Description:
2133 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002134 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002135 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002136 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002137 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002138 cmdStr += " -j"
2139 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002140 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002141 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002142 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002143 except AssertionError:
2144 main.log.exception( "" )
2145 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002146 except TypeError:
2147 main.log.exception( self.name + ": Object not as expected" )
2148 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002149 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002150 main.log.error( self.name + ": EOF exception found" )
2151 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002152 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002153 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002154 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002155 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002156
pingping-lin54b03372015-08-13 14:43:10 -07002157 def ipv4RouteNumber( self ):
2158 """
2159 NOTE: This method should be used after installing application:
2160 onos-app-sdnip
2161 Description:
2162 Obtain the total IPv4 routes number in the system
2163 """
2164 try:
Pratik Parab57963572017-05-09 11:37:54 -07002165 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002166 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002167 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002168 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002169 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002170 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002171 except AssertionError:
2172 main.log.exception( "" )
2173 return None
2174 except ( TypeError, ValueError ):
2175 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002176 return None
2177 except pexpect.EOF:
2178 main.log.error( self.name + ": EOF exception found" )
2179 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002180 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002181 except Exception:
2182 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002183 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002184
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002185 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002186 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002187 """
2188 Description:
2189 Obtain Bandwidth Allocation Information from ONOS cli.
2190 """
2191 try:
2192 cmdStr = "allocations"
2193 if jsonFormat:
2194 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002195 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002196 assert handle is not None, "Error in sendline"
2197 assert "Command not found:" not in handle, handle
2198 return handle
2199 except AssertionError:
2200 main.log.exception( "" )
2201 return None
2202 except ( TypeError, ValueError ):
2203 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2204 return None
2205 except pexpect.EOF:
2206 main.log.error( self.name + ": EOF exception found" )
2207 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002208 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002209 except Exception:
2210 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002211 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002212
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002213 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002214 """
andrewonlabe6745342014-10-17 14:29:13 -04002215 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002216 Obtain intents from the ONOS cli.
2217 Optional:
2218 * jsonFormat: Enable output formatting in json, default to True
2219 * summary: Whether only output the intent summary, defaults to False
2220 * type: Only output a certain type of intent. This options is valid
2221 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002222 """
andrewonlabe6745342014-10-17 14:29:13 -04002223 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002224 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002225 if summary:
2226 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002227 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002228 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002229 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002230 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002231 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002232 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002233 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002234 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002235 else:
Jon Hallff566d52016-01-15 14:45:36 -08002236 intentType = ""
2237 # IF we want the summary of a specific intent type
2238 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002239 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002240 if intentType in jsonResult.keys():
2241 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002242 else:
Jon Hallff566d52016-01-15 14:45:36 -08002243 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002244 return handle
2245 else:
2246 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002247 except AssertionError:
2248 main.log.exception( "" )
2249 return None
2250 except ( TypeError, ValueError ):
2251 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002252 return None
2253 except pexpect.EOF:
2254 main.log.error( self.name + ": EOF exception found" )
2255 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002256 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002257 except Exception:
2258 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002259 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002260
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002261 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002262 """
You Wangfdcbfc42016-05-16 12:16:53 -07002263 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002264 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002265 list of intent IDs.
2266 Parameters:
2267 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002268 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002269 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002270 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002271 accepted.
2272 Returns a list of dictionaries if a list of intent IDs is accepted,
2273 and each dictionary maps 'id' to the Intent ID and 'state' to
2274 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002275 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002276
kelvin-onlab54400a92015-02-26 18:05:51 -08002277 try:
2278 state = "State is Undefined"
2279 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002280 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002281 else:
Jon Hallc6793552016-01-19 14:18:37 -08002282 rawJson = intentsJson
2283 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002284 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002285 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002286 if intentsId == intent[ 'id' ]:
2287 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002288 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002289 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002290 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002291 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002292 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002293 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002294 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002295 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002296 for intent in parsedIntentsJson:
2297 if intentsId[ i ] == intent[ 'id' ]:
2298 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002299 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002300 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002301 break
Jon Hallefbd9792015-03-05 16:11:36 -08002302 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002303 main.log.warn( "Could not find all intents in ONOS output" )
2304 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002305 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002306 else:
Jon Hall53158082017-05-18 11:17:00 -07002307 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002308 return None
Jon Hallc6793552016-01-19 14:18:37 -08002309 except ( TypeError, ValueError ):
2310 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002311 return None
2312 except pexpect.EOF:
2313 main.log.error( self.name + ": EOF exception found" )
2314 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002315 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002316 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002317 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002318 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002319
Jon Hallf539eb92017-05-22 17:18:42 -07002320 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002321 """
2322 Description:
2323 Check intents state
2324 Required:
2325 intentsId - List of intents ID to be checked
2326 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002327 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002328 state in the list.
2329 *NOTE: You can pass in a list of expected state,
2330 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002331 Return:
Jon Hall53158082017-05-18 11:17:00 -07002332 Returns main.TRUE only if all intent are the same as expected states,
2333 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002334 """
2335 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002336 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002337 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002338
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002339 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002340 intentsDict = []
2341 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002342 if isinstance( intentsId, types.StringType ) \
2343 and intent.get( 'id' ) == intentsId:
2344 intentsDict.append( intent )
2345 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002346 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002347 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002348
2349 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002350 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002351 "getting intents state" )
2352 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002353
2354 if isinstance( expectedState, types.StringType ):
2355 for intents in intentsDict:
2356 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002357 main.log.debug( self.name + " : Intent ID - " +
2358 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002359 " actual state = " +
2360 intents.get( 'state' )
2361 + " does not equal expected state = "
2362 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002363 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002364 elif isinstance( expectedState, types.ListType ):
2365 for intents in intentsDict:
2366 if not any( state == intents.get( 'state' ) for state in
2367 expectedState ):
2368 main.log.debug( self.name + " : Intent ID - " +
2369 intents.get( 'id' ) +
2370 " actual state = " +
2371 intents.get( 'state' ) +
2372 " does not equal expected states = "
2373 + str( expectedState ) )
2374 returnValue = main.FALSE
2375
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002376 if returnValue == main.TRUE:
2377 main.log.info( self.name + ": All " +
2378 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002379 " intents are in " + str( expectedState ) +
2380 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002381 return returnValue
2382 except TypeError:
2383 main.log.exception( self.name + ": Object not as expected" )
2384 return None
2385 except pexpect.EOF:
2386 main.log.error( self.name + ": EOF exception found" )
2387 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002388 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002389 except Exception:
2390 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002391 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002392
Jon Hallf539eb92017-05-22 17:18:42 -07002393 def compareBandwidthAllocations( self, expectedAllocations ):
2394 """
2395 Description:
2396 Compare the allocated bandwidth with the given allocations
2397 Required:
2398 expectedAllocations - The expected ONOS output of the allocations command
2399 Return:
2400 Returns main.TRUE only if all intent are the same as expected states,
2401 otherwise returns main.FALSE.
2402 """
2403 # FIXME: Convert these string comparisons to object comparisons
2404 try:
2405 returnValue = main.TRUE
2406 bandwidthFailed = False
2407 rawAlloc = self.allocations()
2408 expectedFormat = StringIO( expectedAllocations )
2409 ONOSOutput = StringIO( rawAlloc )
2410 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2411 str( expectedFormat ) ) )
2412
2413 for actual, expected in izip( ONOSOutput, expectedFormat ):
2414 actual = actual.rstrip()
2415 expected = expected.rstrip()
2416 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2417 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002418 marker1 = actual.find( 'allocated' )
2419 m1 = actual[ :marker1 ]
2420 marker2 = expected.find( 'allocated' )
2421 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002422 if m1 != m2:
2423 bandwidthFailed = True
2424 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2425 bandwidthFailed = True
2426 expectedFormat.close()
2427 ONOSOutput.close()
2428
2429 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002430 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002431 returnValue = main.FALSE
2432 return returnValue
2433 except TypeError:
2434 main.log.exception( self.name + ": Object not as expected" )
2435 return None
2436 except pexpect.EOF:
2437 main.log.error( self.name + ": EOF exception found" )
2438 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002439 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002440 except Exception:
2441 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002442 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002443
You Wang66518af2016-05-16 15:32:59 -07002444 def compareIntent( self, intentDict ):
2445 """
2446 Description:
2447 Compare the intent ids and states provided in the argument with all intents in ONOS
2448 Return:
2449 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2450 Arguments:
2451 intentDict: a dictionary which maps intent ids to intent states
2452 """
2453 try:
2454 intentsRaw = self.intents()
2455 intentsJson = json.loads( intentsRaw )
2456 intentDictONOS = {}
2457 for intent in intentsJson:
2458 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002459 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002460 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002461 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002462 str( len( intentDict ) ) + " expected and " +
2463 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002464 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002465 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002466 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002467 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2468 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002469 else:
2470 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2471 main.log.debug( self.name + ": intent ID - " + intentID +
2472 " expected state is " + intentDict[ intentID ] +
2473 " but actual state is " + intentDictONOS[ intentID ] )
2474 returnValue = main.FALSE
2475 intentDictONOS.pop( intentID )
2476 if len( intentDictONOS ) > 0:
2477 returnValue = main.FALSE
2478 for intentID in intentDictONOS.keys():
2479 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002480 if returnValue == main.TRUE:
2481 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2482 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002483 except KeyError:
2484 main.log.exception( self.name + ": KeyError exception found" )
2485 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002486 except ( TypeError, ValueError ):
2487 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002488 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002489 except pexpect.EOF:
2490 main.log.error( self.name + ": EOF exception found" )
2491 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002492 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002493 except Exception:
2494 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002495 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002496
YPZhang14a4aa92016-07-15 13:37:15 -07002497 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002498 """
2499 Description:
2500 Check the number of installed intents.
2501 Optional:
2502 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002503 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002504 Return:
2505 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2506 , otherwise, returns main.FALSE.
2507 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002508
GlennRCed771242016-01-13 17:02:47 -08002509 try:
2510 cmd = "intents -s -j"
2511
2512 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002513 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002514 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002515 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002516 response = json.loads( response )
2517
2518 # get total and installed number, see if they are match
2519 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002520 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002521 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2522 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002523 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002524 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2525 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002526 return main.FALSE
2527
Jon Hallc6793552016-01-19 14:18:37 -08002528 except ( TypeError, ValueError ):
2529 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002530 return None
2531 except pexpect.EOF:
2532 main.log.error( self.name + ": EOF exception found" )
2533 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002534 if noExit:
2535 return main.FALSE
2536 else:
Devin Lim44075962017-08-11 10:56:37 -07002537 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002538 except pexpect.TIMEOUT:
2539 main.log.error( self.name + ": ONOS timeout" )
2540 return None
GlennRCed771242016-01-13 17:02:47 -08002541 except Exception:
2542 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002543 if noExit:
2544 return main.FALSE
2545 else:
Devin Lim44075962017-08-11 10:56:37 -07002546 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002547
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002548 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002549 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002550 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002551 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002552 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002553 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002554 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002555 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002556 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002557 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002558 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002559 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002560 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002561 cmdStr += " -n"
2562 cmdStr += " " + state
2563 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002564 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002565 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002566 assert "Command not found:" not in handle, handle
2567 if re.search( "Error:", handle ):
2568 main.log.error( self.name + ": flows() response: " +
2569 str( handle ) )
2570 return handle
2571 except AssertionError:
2572 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002573 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002574 except TypeError:
2575 main.log.exception( self.name + ": Object not as expected" )
2576 return None
Jon Hallc6793552016-01-19 14:18:37 -08002577 except pexpect.TIMEOUT:
2578 main.log.error( self.name + ": ONOS timeout" )
2579 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002580 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002581 main.log.error( self.name + ": EOF exception found" )
2582 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002583 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002584 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002585 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002586 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002587
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002588 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002589 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002590 count = int( count ) if count else 0
steven30801a0cc1422019-01-26 10:06:51 +08002591 main.log.debug( "found {} flows".format( count ) )
Jon Halle0f0b342017-04-18 11:43:47 -07002592 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002593
Jon Halle0f0b342017-04-18 11:43:47 -07002594 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002595 """
2596 Description:
GlennRCed771242016-01-13 17:02:47 -08002597 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002598 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2599 if the count of those states is 0, which means all current flows
2600 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002601 Optional:
GlennRCed771242016-01-13 17:02:47 -08002602 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002603 Return:
2604 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002605 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002606 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002607 """
2608 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002609 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002610 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002611 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002612 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002613 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002614 if rawFlows:
2615 # if we didn't get flows or flows function return None, we should return
2616 # main.Flase
2617 checkedStates.append( json.loads( rawFlows ) )
2618 else:
2619 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002620 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002621 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002622 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002623 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002624 except TypeError:
2625 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002626 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002627
GlennRCed771242016-01-13 17:02:47 -08002628 # We want to count PENDING_ADD if isPENDING is true
2629 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002630 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002631 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002632 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002633 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002634 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002635 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002636 except ( TypeError, ValueError ):
2637 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002638 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002639
YPZhang240842b2016-05-17 12:00:50 -07002640 except AssertionError:
2641 main.log.exception( "" )
2642 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002643 except pexpect.TIMEOUT:
2644 main.log.error( self.name + ": ONOS timeout" )
2645 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002646 except pexpect.EOF:
2647 main.log.error( self.name + ": EOF exception found" )
2648 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002649 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002650 except Exception:
2651 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002652 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002653
GlennRCed771242016-01-13 17:02:47 -08002654 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002655 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002656 """
andrewonlab87852b02014-11-19 18:44:19 -05002657 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002658 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002659 a specific point-to-point intent definition
2660 Required:
GlennRCed771242016-01-13 17:02:47 -08002661 * ingress: specify source dpid
2662 * egress: specify destination dpid
2663 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002664 Optional:
GlennRCed771242016-01-13 17:02:47 -08002665 * offset: the keyOffset is where the next batch of intents
2666 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002667 * noExit: If set to True, TestON will not exit if any error when issus command
2668 * getResponse: If set to True, function will return ONOS response.
2669
GlennRCed771242016-01-13 17:02:47 -08002670 Returns: If failed to push test intents, it will returen None,
2671 if successful, return true.
2672 Timeout expection will return None,
2673 TypeError will return false
2674 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002675 """
andrewonlab87852b02014-11-19 18:44:19 -05002676 try:
GlennRCed771242016-01-13 17:02:47 -08002677 if background:
2678 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002679 else:
GlennRCed771242016-01-13 17:02:47 -08002680 back = ""
2681 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002682 ingress,
2683 egress,
2684 batchSize,
2685 offset,
2686 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002687 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002688 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002689 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002690 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002691 if getResponse:
2692 return response
2693
GlennRCed771242016-01-13 17:02:47 -08002694 # TODO: We should handle if there is failure in installation
2695 return main.TRUE
2696
Jon Hallc6793552016-01-19 14:18:37 -08002697 except AssertionError:
2698 main.log.exception( "" )
2699 return None
GlennRCed771242016-01-13 17:02:47 -08002700 except pexpect.TIMEOUT:
2701 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002702 return None
andrewonlab87852b02014-11-19 18:44:19 -05002703 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002704 main.log.error( self.name + ": EOF exception found" )
2705 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002706 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002707 except TypeError:
2708 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002709 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002710 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002711 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002712 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002713
YPZhangebf9eb52016-05-12 15:20:24 -07002714 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002715 """
2716 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002717 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002718 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002719 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002720 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002721 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002722
YPZhangb5d3f832016-01-23 22:54:26 -08002723 try:
YPZhange3109a72016-02-02 11:25:37 -08002724 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002725 cmd = "flows -c added"
2726 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2727 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002728 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002729 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002730 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002731 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002732 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002733 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002734 return None
2735 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002736
You Wangd3cb2ce2016-05-16 14:01:24 -07002737 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002738 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002739 return None
2740 except pexpect.EOF:
2741 main.log.error( self.name + ": EOF exception found" )
2742 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002743 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002744 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002745 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002746 except pexpect.TIMEOUT:
2747 main.log.error( self.name + ": ONOS timeout" )
2748 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002749 except Exception:
2750 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002751 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002752 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002753 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002754
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002755 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002756 """
2757 Description:
2758 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002759 Optional:
2760 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002761 Return:
2762 The number of intents
2763 """
2764 try:
2765 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002766 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002767 if response is None:
2768 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002769 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002770 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002771 except ( TypeError, ValueError ):
2772 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002773 return None
2774 except pexpect.EOF:
2775 main.log.error( self.name + ": EOF exception found" )
2776 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002777 if noExit:
2778 return -1
2779 else:
Devin Lim44075962017-08-11 10:56:37 -07002780 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002781 except Exception:
2782 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002783 if noExit:
2784 return -1
2785 else:
Devin Lim44075962017-08-11 10:56:37 -07002786 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002787
kelvin-onlabd3b64892015-01-20 13:26:24 -08002788 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002789 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002790 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002791 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002792 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002793 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002794 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002795 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002796 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002797 cmdStr += " -j"
2798 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002799 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002800 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002801 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002802 except AssertionError:
2803 main.log.exception( "" )
2804 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002805 except TypeError:
2806 main.log.exception( self.name + ": Object not as expected" )
2807 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002808 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002809 main.log.error( self.name + ": EOF exception found" )
2810 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002811 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002812 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002813 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002814 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002815
kelvin-onlabd3b64892015-01-20 13:26:24 -08002816 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002817 """
2818 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002819 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002820 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002821 """
andrewonlab867212a2014-10-22 20:13:38 -04002822 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002823 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002824 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002825 cmdStr += " -j"
2826 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002827 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002828 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002829 if handle:
2830 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002831 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002832 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002833 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002834 else:
2835 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002836 except AssertionError:
2837 main.log.exception( "" )
2838 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002839 except TypeError:
2840 main.log.exception( self.name + ": Object not as expected" )
2841 return None
andrewonlab867212a2014-10-22 20:13:38 -04002842 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002843 main.log.error( self.name + ": EOF exception found" )
2844 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002845 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002846 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002847 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002848 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002849
kelvin8ec71442015-01-15 16:57:00 -08002850 # Wrapper functions ****************
2851 # Wrapper functions use existing driver
2852 # functions and extends their use case.
2853 # For example, we may use the output of
2854 # a normal driver function, and parse it
2855 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002856
kelvin-onlabd3b64892015-01-20 13:26:24 -08002857 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002858 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002859 Description:
2860 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002861 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002862 try:
kelvin8ec71442015-01-15 16:57:00 -08002863 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002864 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002865 if intentsStr is None:
2866 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002867 # Convert to a dictionary
2868 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002869 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002870 for intent in intents:
2871 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002872 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002873 except TypeError:
2874 main.log.exception( self.name + ": Object not as expected" )
2875 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002876 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002877 main.log.error( self.name + ": EOF exception found" )
2878 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002879 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002880 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002881 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002882 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002883
You Wang3c276252016-09-21 15:21:36 -07002884 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002885 """
2886 Determine the number of flow rules for the given device id that are
2887 in the added state
You Wang3c276252016-09-21 15:21:36 -07002888 Params:
2889 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002890 """
2891 try:
You Wang3c276252016-09-21 15:21:36 -07002892 if core:
2893 cmdStr = "flows any " + str( deviceId ) + " | " +\
2894 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2895 else:
2896 cmdStr = "flows any " + str( deviceId ) + " | " +\
2897 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002898 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002899 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002900 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002901 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002902 except AssertionError:
2903 main.log.exception( "" )
2904 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002905 except pexpect.EOF:
2906 main.log.error( self.name + ": EOF exception found" )
2907 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002908 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002909 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002910 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002911 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002912
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002913 def groupAddedCount( self, deviceId, core=False ):
2914 """
2915 Determine the number of group rules for the given device id that are
2916 in the added state
2917 Params:
2918 core: if True, only return the number of core groups added
2919 """
2920 try:
2921 if core:
2922 cmdStr = "groups any " + str( deviceId ) + " | " +\
2923 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2924 else:
2925 cmdStr = "groups any " + str( deviceId ) + " | " +\
2926 "grep 'state=ADDED' | wc -l"
2927 handle = self.sendline( cmdStr )
2928 assert handle is not None, "Error in sendline"
2929 assert "Command not found:" not in handle, handle
2930 return handle
2931 except AssertionError:
2932 main.log.exception( "" )
2933 return None
2934 except pexpect.EOF:
2935 main.log.error( self.name + ": EOF exception found" )
2936 main.log.error( self.name + ": " + self.handle.before )
2937 main.cleanAndExit()
2938 except Exception:
2939 main.log.exception( self.name + ": Uncaught exception!" )
2940 main.cleanAndExit()
2941
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002942 def addStaticRoute( self, subnet, intf):
2943 """
2944 Adds a static route to onos.
2945 Params:
2946 subnet: The subnet reaching through this route
2947 intf: The interface this route is reachable through
2948 """
2949 try:
2950 cmdStr = "route-add " + subnet + " " + intf
2951 handle = self.sendline( cmdStr )
2952 assert handle is not None, "Error in sendline"
2953 assert "Command not found:" not in handle, handle
2954 return handle
2955 except AssertionError:
2956 main.log.exception( "" )
2957 return None
2958 except pexpect.EOF:
2959 main.log.error( self.name + ": EOF exception found" )
2960 main.log.error( self.name + ": " + self.handle.before )
2961 main.cleanAndExit()
2962 except Exception:
2963 main.log.exception( self.name + ": Uncaught exception!" )
2964 main.cleanAndExit()
2965
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002966 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
2967 """
2968 Description:
2969 Check whether the number of groups for the given device id that
2970 are in ADDED state is bigger than minGroupCount.
2971 Required:
2972 * deviceId: device id to check the number of added group rules
2973 Optional:
2974 * minGroupCount: the number of groups to compare
2975 * core: if True, only check the number of core groups added
2976 * comparison: if 0, compare with greater than minFlowCount
2977 * if 1, compare with equal to minFlowCount
2978 Return:
2979 Returns the number of groups if it is bigger than minGroupCount,
2980 returns main.FALSE otherwise.
2981 """
2982 count = self.groupAddedCount( deviceId, core )
2983 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07002984 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002985 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
2986
You Wangc02f3be2018-05-18 12:14:23 -07002987 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002988 """
2989 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07002990 deviceId: Id of the device from which we retrieve groups
2991 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002992 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002993 try:
You Wangc02f3be2018-05-18 12:14:23 -07002994 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
2995 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002996 assert handle is not None, "Error in sendline"
2997 assert "Command not found:" not in handle, handle
2998 return handle
2999 except AssertionError:
3000 main.log.exception( "" )
3001 return None
3002 except TypeError:
3003 main.log.exception( self.name + ": Object not as expected" )
3004 return None
3005 except pexpect.EOF:
3006 main.log.error( self.name + ": EOF exception found" )
3007 main.log.error( self.name + ": " + self.handle.before )
3008 main.cleanAndExit()
3009 except Exception:
3010 main.log.exception( self.name + ": Uncaught exception!" )
3011 main.cleanAndExit()
3012
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003013 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003014 """
3015 Description:
3016 Check whether the number of flow rules for the given device id that
3017 are in ADDED state is bigger than minFlowCount.
3018 Required:
3019 * deviceId: device id to check the number of added flow rules
3020 Optional:
3021 * minFlowCount: the number of flow rules to compare
3022 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003023 * comparison: if 0, compare with greater than minFlowCount
3024 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003025 Return:
3026 Returns the number of flow rules if it is bigger than minFlowCount,
3027 returns main.FALSE otherwise.
3028 """
3029 count = self.flowAddedCount( deviceId, core )
3030 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003031 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003032 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003033
kelvin-onlabd3b64892015-01-20 13:26:24 -08003034 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003035 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003036 Use 'devices' function to obtain list of all devices
3037 and parse the result to obtain a list of all device
3038 id's. Returns this list. Returns empty list if no
3039 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003040 List is ordered sequentially
3041
andrewonlab3e15ead2014-10-15 14:21:34 -04003042 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003043 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003044 the ids. By obtaining the list of device ids on the fly,
3045 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003046 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003047 try:
kelvin8ec71442015-01-15 16:57:00 -08003048 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003049 devicesStr = self.devices( jsonFormat=False )
3050 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003051
kelvin-onlabd3b64892015-01-20 13:26:24 -08003052 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003053 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003054 return idList
kelvin8ec71442015-01-15 16:57:00 -08003055
3056 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003057 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003058 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003059 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003060 # Split list further into arguments before and after string
3061 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003062 # append to idList
3063 for arg in tempList:
3064 idList.append( arg.split( "id=" )[ 1 ] )
3065 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003066
Jon Halld4d4b372015-01-28 16:02:41 -08003067 except TypeError:
3068 main.log.exception( self.name + ": Object not as expected" )
3069 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003070 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003071 main.log.error( self.name + ": EOF exception found" )
3072 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003073 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003074 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003075 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003076 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003077
kelvin-onlabd3b64892015-01-20 13:26:24 -08003078 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003079 """
andrewonlab7c211572014-10-15 16:45:20 -04003080 Uses 'nodes' function to obtain list of all nodes
3081 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003082 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003083 Returns:
3084 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003085 """
andrewonlab7c211572014-10-15 16:45:20 -04003086 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003087 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003088 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003089 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003090 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003091 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003092 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003093 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003094 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003095 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003096 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003097 except ( TypeError, ValueError ):
3098 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003099 return None
andrewonlab7c211572014-10-15 16:45:20 -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()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003107
kelvin-onlabd3b64892015-01-20 13:26:24 -08003108 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003109 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003110 Return the first device from the devices api whose 'id' contains 'dpid'
3111 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003112 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003113 try:
kelvin8ec71442015-01-15 16:57:00 -08003114 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003115 return None
3116 else:
kelvin8ec71442015-01-15 16:57:00 -08003117 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003118 rawDevices = self.devices()
3119 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003120 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003121 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003122 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3123 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003124 return device
3125 return None
Jon Hallc6793552016-01-19 14:18:37 -08003126 except ( TypeError, ValueError ):
3127 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003128 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003129 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003130 main.log.error( self.name + ": EOF exception found" )
3131 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003132 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003133 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003134 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003135 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003136
You Wang24139872016-05-03 11:48:47 -07003137 def getTopology( self, topologyOutput ):
3138 """
3139 Definition:
3140 Loads a json topology output
3141 Return:
3142 topology = current ONOS topology
3143 """
3144 import json
3145 try:
3146 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003147 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003148 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003149 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003150 except ( TypeError, ValueError ):
3151 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3152 return None
You Wang24139872016-05-03 11:48:47 -07003153 except pexpect.EOF:
3154 main.log.error( self.name + ": EOF exception found" )
3155 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003156 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003157 except Exception:
3158 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003159 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003160
Pier6a0c4de2018-03-18 16:01:30 -07003161 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003162 """
Jon Hallefbd9792015-03-05 16:11:36 -08003163 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003164 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003165 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003166
Flavio Castro82ee2f62016-06-07 15:04:12 -07003167 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003168 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003169 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003170 logLevel = level to log to.
3171 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003172
Jon Hallefbd9792015-03-05 16:11:36 -08003173 Returns: main.TRUE if the number of switches and links are correct,
3174 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003175 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003176 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003177 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003178 try:
You Wang13310252016-07-31 10:56:14 -07003179 summary = self.summary()
3180 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003181 except ( TypeError, ValueError ):
3182 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3183 return main.ERROR
3184 try:
3185 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003186 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003187 return main.ERROR
3188 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003189 # Is the number of switches is what we expected
3190 devices = topology.get( 'devices', False )
3191 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003192 nodes = summary.get( 'nodes', False )
3193 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003194 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003195 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003196 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003197 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003198 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3199 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003200 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003201 output = output + "The number of links and switches match "\
3202 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003203 result = main.TRUE
3204 else:
You Wang24139872016-05-03 11:48:47 -07003205 output = output + \
3206 "The number of links and switches does not match " + \
3207 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003208 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003209 output = output + "\n ONOS sees %i devices" % int( devices )
3210 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003211 if int( numolink ) > 0:
3212 output = output + "and %i links " % int( links )
3213 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003214 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003215 output = output + "and %i controllers " % int( nodes )
3216 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003217 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003218 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003219 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003220 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003221 else:
You Wang24139872016-05-03 11:48:47 -07003222 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003223 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003224 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003225 main.log.error( self.name + ": EOF exception found" )
3226 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003227 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003228 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003229 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003230 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003231
kelvin-onlabd3b64892015-01-20 13:26:24 -08003232 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003233 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003234 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003235 deviceId must be the id of a device as seen in the onos devices command
3236 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003237 role must be either master, standby, or none
3238
Jon Halle3f39ff2015-01-13 11:50:53 -08003239 Returns:
3240 main.TRUE or main.FALSE based on argument verification and
3241 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003242 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003243 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003244 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003245 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003246 cmdStr = "device-role " +\
3247 str( deviceId ) + " " +\
3248 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003249 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003250 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003251 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003252 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003253 if re.search( "Error", handle ):
3254 # end color output to escape any colours
3255 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003256 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003257 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003258 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003259 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003260 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003261 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003262 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003263 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003264 except AssertionError:
3265 main.log.exception( "" )
3266 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003267 except TypeError:
3268 main.log.exception( self.name + ": Object not as expected" )
3269 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003270 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003271 main.log.error( self.name + ": EOF exception found" )
3272 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003273 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003274 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003275 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003276 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003277
kelvin-onlabd3b64892015-01-20 13:26:24 -08003278 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003279 """
Jon Hall0dd09952018-04-19 09:59:11 -07003280 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003281 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003282 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003283 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003284 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003285 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003286 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003287 cmdStr += " -j"
3288 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003289 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003290 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003291 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003292 except AssertionError:
3293 main.log.exception( "" )
3294 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003295 except TypeError:
3296 main.log.exception( self.name + ": Object not as expected" )
3297 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003298 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003299 main.log.error( self.name + ": EOF exception found" )
3300 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003301 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003302 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003303 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003304 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003305
kelvin-onlabd3b64892015-01-20 13:26:24 -08003306 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003307 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003308 CLI command to get the current leader for the Election test application
3309 NOTE: Requires installation of the onos-app-election feature
3310 Returns: Node IP of the leader if one exists
3311 None if none exists
3312 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003313 """
Jon Hall94fd0472014-12-08 11:52:42 -08003314 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003315 cmdStr = "election-test-leader"
3316 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003317 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003318 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003319 # Leader
3320 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003321 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003322 nodeSearch = re.search( leaderPattern, response )
3323 if nodeSearch:
3324 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003325 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003326 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003327 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003328 # no leader
3329 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003330 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003331 nullSearch = re.search( nullPattern, response )
3332 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003333 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003334 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003335 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003336 # error
Jon Hall0e240372018-05-02 11:21:57 -07003337 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003338 ": " + "unexpected response" )
3339 main.log.error( repr( response ) )
3340 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003341 except AssertionError:
3342 main.log.exception( "" )
3343 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003344 except TypeError:
3345 main.log.exception( self.name + ": Object not as expected" )
3346 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003347 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003348 main.log.error( self.name + ": EOF exception found" )
3349 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003350 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003351 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003352 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003353 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003354
kelvin-onlabd3b64892015-01-20 13:26:24 -08003355 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003356 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003357 CLI command to run for leadership of the Election test application.
3358 NOTE: Requires installation of the onos-app-election feature
3359 Returns: Main.TRUE on success
3360 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003361 """
Jon Hall94fd0472014-12-08 11:52:42 -08003362 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003363 cmdStr = "election-test-run"
3364 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003365 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003366 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003367 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003368 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003369 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003370 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003371 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003372 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003373 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003374 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003375 # error
Jon Hall0e240372018-05-02 11:21:57 -07003376 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003377 ": " + "unexpected response" )
3378 main.log.error( repr( response ) )
3379 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003380 except AssertionError:
3381 main.log.exception( "" )
3382 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003383 except TypeError:
3384 main.log.exception( self.name + ": Object not as expected" )
3385 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003386 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003387 main.log.error( self.name + ": EOF exception found" )
3388 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003389 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003390 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003391 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003392 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003393
kelvin-onlabd3b64892015-01-20 13:26:24 -08003394 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003395 """
Jon Hall94fd0472014-12-08 11:52:42 -08003396 * CLI command to withdraw the local node from leadership election for
3397 * the Election test application.
3398 #NOTE: Requires installation of the onos-app-election feature
3399 Returns: Main.TRUE on success
3400 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003401 """
Jon Hall94fd0472014-12-08 11:52:42 -08003402 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003403 cmdStr = "election-test-withdraw"
3404 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003405 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003406 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003407 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003408 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003409 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003410 if re.search( successPattern, response ):
3411 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003412 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003413 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003414 # error
Jon Hall0e240372018-05-02 11:21:57 -07003415 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003416 self.name + ": " + "unexpected response" )
3417 main.log.error( repr( response ) )
3418 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003419 except AssertionError:
3420 main.log.exception( "" )
3421 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003422 except TypeError:
3423 main.log.exception( self.name + ": Object not as expected" )
3424 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003425 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003426 main.log.error( self.name + ": EOF exception found" )
3427 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003428 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003429 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003430 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003431 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003432
kelvin8ec71442015-01-15 16:57:00 -08003433 def getDevicePortsEnabledCount( self, dpid ):
3434 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003435 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003436 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003437 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003438 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003439 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3440 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003441 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003442 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003443 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003444 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003445 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003446 return output
Jon Hallc6793552016-01-19 14:18:37 -08003447 except AssertionError:
3448 main.log.exception( "" )
3449 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003450 except TypeError:
3451 main.log.exception( self.name + ": Object not as expected" )
3452 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003453 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003454 main.log.error( self.name + ": EOF exception found" )
3455 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003456 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003457 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003458 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003459 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003460
kelvin8ec71442015-01-15 16:57:00 -08003461 def getDeviceLinksActiveCount( self, dpid ):
3462 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003463 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003464 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003465 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003466 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003467 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3468 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003469 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003470 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003471 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003472 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003473 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003474 return output
Jon Hallc6793552016-01-19 14:18:37 -08003475 except AssertionError:
3476 main.log.exception( "" )
3477 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003478 except TypeError:
3479 main.log.exception( self.name + ": Object not as expected" )
3480 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003481 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003482 main.log.error( self.name + ": EOF exception found" )
3483 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003484 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003485 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003486 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003487 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003488
kelvin8ec71442015-01-15 16:57:00 -08003489 def getAllIntentIds( self ):
3490 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003491 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003492 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003493 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003494 cmdStr = "onos:intents | grep id="
3495 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003496 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003497 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003498 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003499 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003500 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003501 return output
Jon Hallc6793552016-01-19 14:18:37 -08003502 except AssertionError:
3503 main.log.exception( "" )
3504 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003505 except TypeError:
3506 main.log.exception( self.name + ": Object not as expected" )
3507 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003508 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003509 main.log.error( self.name + ": EOF exception found" )
3510 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003511 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003512 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003513 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003514 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003515
Jon Hall73509952015-02-24 16:42:56 -08003516 def intentSummary( self ):
3517 """
Jon Hallefbd9792015-03-05 16:11:36 -08003518 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003519 """
3520 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003521 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003522 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003523 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003524 states.append( intent.get( 'state', None ) )
3525 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003526 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003527 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003528 except ( TypeError, ValueError ):
3529 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003530 return None
3531 except pexpect.EOF:
3532 main.log.error( self.name + ": EOF exception found" )
3533 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003534 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003535 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003536 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003537 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003538
Jon Hall61282e32015-03-19 11:34:11 -07003539 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003540 """
3541 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003542 Optional argument:
3543 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003544 """
Jon Hall63604932015-02-26 17:09:50 -08003545 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003546 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003547 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003548 cmdStr += " -j"
3549 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003550 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003551 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003552 return output
Jon Hallc6793552016-01-19 14:18:37 -08003553 except AssertionError:
3554 main.log.exception( "" )
3555 return None
Jon Hall63604932015-02-26 17:09:50 -08003556 except TypeError:
3557 main.log.exception( self.name + ": Object not as expected" )
3558 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003559 except pexpect.EOF:
3560 main.log.error( self.name + ": EOF exception found" )
3561 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003562 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003563 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003564 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003565 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003566
acsmarsa4a4d1e2015-07-10 16:01:24 -07003567 def leaderCandidates( self, jsonFormat=True ):
3568 """
3569 Returns the output of the leaders -c command.
3570 Optional argument:
3571 * jsonFormat - boolean indicating if you want output in json
3572 """
3573 try:
3574 cmdStr = "onos:leaders -c"
3575 if jsonFormat:
3576 cmdStr += " -j"
3577 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003578 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003579 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003580 return output
Jon Hallc6793552016-01-19 14:18:37 -08003581 except AssertionError:
3582 main.log.exception( "" )
3583 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003584 except TypeError:
3585 main.log.exception( self.name + ": Object not as expected" )
3586 return None
3587 except pexpect.EOF:
3588 main.log.error( self.name + ": EOF exception found" )
3589 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003590 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003591 except Exception:
3592 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003593 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003594
Jon Hallc6793552016-01-19 14:18:37 -08003595 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003596 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003597 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003598 topic parameter and an empty list if the topic doesn't exist
3599 If no leader is elected leader in the returned list will be "none"
3600 Returns None if there is a type error processing the json object
3601 """
3602 try:
Jon Hall6e709752016-02-01 13:38:46 -08003603 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003604 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003605 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003606 assert "Command not found:" not in rawOutput, rawOutput
3607 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003608 results = []
3609 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003610 if dict[ "topic" ] == topic:
3611 leader = dict[ "leader" ]
3612 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003613 results.append( leader )
3614 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003615 return results
Jon Hallc6793552016-01-19 14:18:37 -08003616 except AssertionError:
3617 main.log.exception( "" )
3618 return None
3619 except ( TypeError, ValueError ):
3620 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003621 return None
3622 except pexpect.EOF:
3623 main.log.error( self.name + ": EOF exception found" )
3624 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003625 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003626 except Exception:
3627 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003628 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003629
Jon Hall61282e32015-03-19 11:34:11 -07003630 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003631 """
3632 Returns the output of the intent Pending map.
3633 """
Jon Hall63604932015-02-26 17:09:50 -08003634 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003635 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003636 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003637 cmdStr += " -j"
3638 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003639 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003640 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003641 return output
Jon Hallc6793552016-01-19 14:18:37 -08003642 except AssertionError:
3643 main.log.exception( "" )
3644 return None
Jon Hall63604932015-02-26 17:09:50 -08003645 except TypeError:
3646 main.log.exception( self.name + ": Object not as expected" )
3647 return None
3648 except pexpect.EOF:
3649 main.log.error( self.name + ": EOF exception found" )
3650 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003651 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003652 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003653 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003654 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003655
Jon Hall2c8959e2016-12-16 12:17:34 -08003656 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003657 """
3658 Returns the output of the raft partitions command for ONOS.
3659 """
Jon Hall61282e32015-03-19 11:34:11 -07003660 # Sample JSON
3661 # {
3662 # "leader": "tcp://10.128.30.11:7238",
3663 # "members": [
3664 # "tcp://10.128.30.11:7238",
3665 # "tcp://10.128.30.17:7238",
3666 # "tcp://10.128.30.13:7238",
3667 # ],
3668 # "name": "p1",
3669 # "term": 3
3670 # },
Jon Hall63604932015-02-26 17:09:50 -08003671 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003672 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003673 if candidates:
3674 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003675 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003676 cmdStr += " -j"
3677 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003678 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003679 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003680 return output
Jon Hallc6793552016-01-19 14:18:37 -08003681 except AssertionError:
3682 main.log.exception( "" )
3683 return None
Jon Hall63604932015-02-26 17:09:50 -08003684 except TypeError:
3685 main.log.exception( self.name + ": Object not as expected" )
3686 return None
3687 except pexpect.EOF:
3688 main.log.error( self.name + ": EOF exception found" )
3689 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003690 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003691 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003692 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003693 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003694
Jon Halle9f909e2016-09-23 10:43:12 -07003695 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003696 """
3697 Returns the output of the apps command for ONOS. This command lists
3698 information about installed ONOS applications
3699 """
3700 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003701 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003702 # "description":"ONOS OpenFlow protocol southbound providers",
3703 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003704 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003705 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003706 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003707 if summary:
3708 cmdStr += " -s"
3709 if active:
3710 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003711 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003712 cmdStr += " -j"
3713 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003714 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003715 assert "Command not found:" not in output, output
3716 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003717 return output
Jon Hallbe379602015-03-24 13:39:32 -07003718 # FIXME: look at specific exceptions/Errors
3719 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003720 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003721 return None
3722 except TypeError:
3723 main.log.exception( self.name + ": Object not as expected" )
3724 return None
3725 except pexpect.EOF:
3726 main.log.error( self.name + ": EOF exception found" )
3727 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003728 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003729 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003730 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003731 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003732
You Wangcdc51fe2018-08-12 17:14:56 -07003733 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003734 """
3735 Uses the onos:apps cli command to return the status of an application.
3736 Returns:
3737 "ACTIVE" - If app is installed and activated
3738 "INSTALLED" - If app is installed and deactivated
3739 "UNINSTALLED" - If app is not installed
3740 None - on error
3741 """
Jon Hall146f1522015-03-24 15:33:24 -07003742 try:
3743 if not isinstance( appName, types.StringType ):
3744 main.log.error( self.name + ".appStatus(): appName must be" +
3745 " a string" )
3746 return None
3747 output = self.apps( jsonFormat=True )
3748 appsJson = json.loads( output )
3749 state = None
3750 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003751 if appName == app.get( 'name' ):
3752 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003753 break
3754 if state == "ACTIVE" or state == "INSTALLED":
3755 return state
3756 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003757 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003758 return "UNINSTALLED"
3759 elif state:
3760 main.log.error( "Unexpected state from 'onos:apps': " +
3761 str( state ) )
3762 return state
Jon Hallc6793552016-01-19 14:18:37 -08003763 except ( TypeError, ValueError ):
3764 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003765 return None
3766 except pexpect.EOF:
3767 main.log.error( self.name + ": EOF exception found" )
3768 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003769 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003770 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003771 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003772 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003773
Jon Hallbe379602015-03-24 13:39:32 -07003774 def app( self, appName, option ):
3775 """
3776 Interacts with the app command for ONOS. This command manages
3777 application inventory.
3778 """
Jon Hallbe379602015-03-24 13:39:32 -07003779 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003780 # Validate argument types
3781 valid = True
3782 if not isinstance( appName, types.StringType ):
3783 main.log.error( self.name + ".app(): appName must be a " +
3784 "string" )
3785 valid = False
3786 if not isinstance( option, types.StringType ):
3787 main.log.error( self.name + ".app(): option must be a string" )
3788 valid = False
3789 if not valid:
3790 return main.FALSE
3791 # Validate Option
3792 option = option.lower()
3793 # NOTE: Install may become a valid option
3794 if option == "activate":
3795 pass
3796 elif option == "deactivate":
3797 pass
3798 elif option == "uninstall":
3799 pass
3800 else:
3801 # Invalid option
3802 main.log.error( "The ONOS app command argument only takes " +
3803 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003804 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003805 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003806 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003807 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003808 assert output is not None, "Error in sendline"
3809 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003810 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003811 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003812 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003813 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003814 elif "No such application" in output:
3815 main.log.error( "The application '" + appName +
3816 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003817 return main.FALSE
3818 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003819 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003820 str( output ) )
3821 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003822 elif "Unsupported command:" in output:
3823 main.log.error( "Incorrect command given to 'app': " +
3824 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003825 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003826 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003827 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003828 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003829 except AssertionError:
3830 main.log.exception( self.name + ": AssertionError exception found" )
3831 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003832 except TypeError:
3833 main.log.exception( self.name + ": Object not as expected" )
3834 return main.ERROR
3835 except pexpect.EOF:
3836 main.log.error( self.name + ": EOF exception found" )
3837 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003838 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003839 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003840 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003841 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003842
Jon Hallbd16b922015-03-26 17:53:15 -07003843 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003844 """
3845 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003846 appName is the hierarchical app name, not the feature name
3847 If check is True, method will check the status of the app after the
3848 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003849 Returns main.TRUE if the command was successfully sent
3850 main.FALSE if the cli responded with an error or given
3851 incorrect input
3852 """
3853 try:
3854 if not isinstance( appName, types.StringType ):
3855 main.log.error( self.name + ".activateApp(): appName must be" +
3856 " a string" )
3857 return main.FALSE
3858 status = self.appStatus( appName )
3859 if status == "INSTALLED":
3860 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003861 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003862 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003863 status = self.appStatus( appName )
3864 if status == "ACTIVE":
3865 return main.TRUE
3866 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003867 main.log.debug( "The state of application " +
3868 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003869 time.sleep( 1 )
3870 return main.FALSE
3871 else: # not 'check' or command didn't succeed
3872 return response
Jon Hall146f1522015-03-24 15:33:24 -07003873 elif status == "ACTIVE":
3874 return main.TRUE
3875 elif status == "UNINSTALLED":
3876 main.log.error( self.name + ": Tried to activate the " +
3877 "application '" + appName + "' which is not " +
3878 "installed." )
3879 else:
3880 main.log.error( "Unexpected return value from appStatus: " +
3881 str( status ) )
3882 return main.ERROR
3883 except TypeError:
3884 main.log.exception( self.name + ": Object not as expected" )
3885 return main.ERROR
3886 except pexpect.EOF:
3887 main.log.error( self.name + ": EOF exception found" )
3888 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003889 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003890 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003891 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003892 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003893
Jon Hallbd16b922015-03-26 17:53:15 -07003894 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003895 """
3896 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003897 appName is the hierarchical app name, not the feature name
3898 If check is True, method will check the status of the app after the
3899 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003900 Returns main.TRUE if the command was successfully sent
3901 main.FALSE if the cli responded with an error or given
3902 incorrect input
3903 """
3904 try:
3905 if not isinstance( appName, types.StringType ):
3906 main.log.error( self.name + ".deactivateApp(): appName must " +
3907 "be a string" )
3908 return main.FALSE
3909 status = self.appStatus( appName )
3910 if status == "INSTALLED":
3911 return main.TRUE
3912 elif status == "ACTIVE":
3913 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003914 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003915 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003916 status = self.appStatus( appName )
3917 if status == "INSTALLED":
3918 return main.TRUE
3919 else:
3920 time.sleep( 1 )
3921 return main.FALSE
3922 else: # not check or command didn't succeed
3923 return response
Jon Hall146f1522015-03-24 15:33:24 -07003924 elif status == "UNINSTALLED":
3925 main.log.warn( self.name + ": Tried to deactivate the " +
3926 "application '" + appName + "' which is not " +
3927 "installed." )
3928 return main.TRUE
3929 else:
3930 main.log.error( "Unexpected return value from appStatus: " +
3931 str( status ) )
3932 return main.ERROR
3933 except TypeError:
3934 main.log.exception( self.name + ": Object not as expected" )
3935 return main.ERROR
3936 except pexpect.EOF:
3937 main.log.error( self.name + ": EOF exception found" )
3938 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003939 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003940 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003941 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003942 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003943
Jon Hallbd16b922015-03-26 17:53:15 -07003944 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003945 """
3946 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003947 appName is the hierarchical app name, not the feature name
3948 If check is True, method will check the status of the app after the
3949 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003950 Returns main.TRUE if the command was successfully sent
3951 main.FALSE if the cli responded with an error or given
3952 incorrect input
3953 """
3954 # TODO: check with Thomas about the state machine for apps
3955 try:
3956 if not isinstance( appName, types.StringType ):
3957 main.log.error( self.name + ".uninstallApp(): appName must " +
3958 "be a string" )
3959 return main.FALSE
3960 status = self.appStatus( appName )
3961 if status == "INSTALLED":
3962 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003963 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003964 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003965 status = self.appStatus( appName )
3966 if status == "UNINSTALLED":
3967 return main.TRUE
3968 else:
3969 time.sleep( 1 )
3970 return main.FALSE
3971 else: # not check or command didn't succeed
3972 return response
Jon Hall146f1522015-03-24 15:33:24 -07003973 elif status == "ACTIVE":
3974 main.log.warn( self.name + ": Tried to uninstall the " +
3975 "application '" + appName + "' which is " +
3976 "currently active." )
3977 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003978 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003979 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003980 status = self.appStatus( appName )
3981 if status == "UNINSTALLED":
3982 return main.TRUE
3983 else:
3984 time.sleep( 1 )
3985 return main.FALSE
3986 else: # not check or command didn't succeed
3987 return response
Jon Hall146f1522015-03-24 15:33:24 -07003988 elif status == "UNINSTALLED":
3989 return main.TRUE
3990 else:
3991 main.log.error( "Unexpected return value from appStatus: " +
3992 str( status ) )
3993 return main.ERROR
3994 except TypeError:
3995 main.log.exception( self.name + ": Object not as expected" )
3996 return main.ERROR
3997 except pexpect.EOF:
3998 main.log.error( self.name + ": EOF exception found" )
3999 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004000 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004001 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004002 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004003 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004004
4005 def appIDs( self, jsonFormat=True ):
4006 """
4007 Show the mappings between app id and app names given by the 'app-ids'
4008 cli command
4009 """
4010 try:
4011 cmdStr = "app-ids"
4012 if jsonFormat:
4013 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004014 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004015 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004016 assert "Command not found:" not in output, output
4017 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004018 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004019 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004020 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004021 return None
4022 except TypeError:
4023 main.log.exception( self.name + ": Object not as expected" )
4024 return None
4025 except pexpect.EOF:
4026 main.log.error( self.name + ": EOF exception found" )
4027 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004028 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004029 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004030 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004031 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004032
4033 def appToIDCheck( self ):
4034 """
4035 This method will check that each application's ID listed in 'apps' is
4036 the same as the ID listed in 'app-ids'. The check will also check that
4037 there are no duplicate IDs issued. Note that an app ID should be
4038 a globaly unique numerical identifier for app/app-like features. Once
4039 an ID is registered, the ID is never freed up so that if an app is
4040 reinstalled it will have the same ID.
4041
4042 Returns: main.TRUE if the check passes and
4043 main.FALSE if the check fails or
4044 main.ERROR if there is some error in processing the test
4045 """
4046 try:
Jon Hall0e240372018-05-02 11:21:57 -07004047 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004048 rawJson = self.appIDs( jsonFormat=True )
4049 if rawJson:
4050 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004051 else:
Jon Hall0e240372018-05-02 11:21:57 -07004052 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4053 return main.FALSE
4054
4055 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004056 rawJson = self.apps( jsonFormat=True )
4057 if rawJson:
4058 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004059 else:
Jon Hallc6793552016-01-19 14:18:37 -08004060 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004061 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004062
Jon Hallbd16b922015-03-26 17:53:15 -07004063 result = main.TRUE
4064 for app in apps:
4065 appID = app.get( 'id' )
4066 if appID is None:
4067 main.log.error( "Error parsing app: " + str( app ) )
4068 result = main.FALSE
4069 appName = app.get( 'name' )
4070 if appName is None:
4071 main.log.error( "Error parsing app: " + str( app ) )
4072 result = main.FALSE
4073 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004074 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004075 if not current: # if ids doesn't have this id
4076 result = main.FALSE
4077 main.log.error( "'app-ids' does not have the ID for " +
4078 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004079 main.log.debug( "apps command returned: " + str( app ) +
4080 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004081 elif len( current ) > 1:
4082 # there is more than one app with this ID
4083 result = main.FALSE
4084 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004085 elif not current[ 0 ][ 'name' ] == appName:
4086 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004087 result = main.FALSE
4088 main.log.error( "'app-ids' has " + str( currentName ) +
4089 " registered under id:" + str( appID ) +
4090 " but 'apps' has " + str( appName ) )
4091 else:
4092 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004093
Jon Hallbd16b922015-03-26 17:53:15 -07004094 # now make sure that app-ids has no duplicates
4095 idsList = []
4096 namesList = []
4097 for item in ids:
4098 idsList.append( item[ 'id' ] )
4099 namesList.append( item[ 'name' ] )
4100 if len( idsList ) != len( set( idsList ) ) or\
4101 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004102 main.log.error( "'app-ids' has some duplicate entries: \n"
4103 + json.dumps( ids,
4104 sort_keys=True,
4105 indent=4,
4106 separators=( ',', ': ' ) ) )
4107 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004108 return result
Jon Hallc6793552016-01-19 14:18:37 -08004109 except ( TypeError, ValueError ):
4110 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004111 return main.ERROR
4112 except pexpect.EOF:
4113 main.log.error( self.name + ": EOF exception found" )
4114 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004115 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004116 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004117 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004118 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004119
Jon Hallfb760a02015-04-13 15:35:03 -07004120 def getCfg( self, component=None, propName=None, short=False,
4121 jsonFormat=True ):
4122 """
4123 Get configuration settings from onos cli
4124 Optional arguments:
4125 component - Optionally only list configurations for a specific
4126 component. If None, all components with configurations
4127 are displayed. Case Sensitive string.
4128 propName - If component is specified, propName option will show
4129 only this specific configuration from that component.
4130 Case Sensitive string.
4131 jsonFormat - Returns output as json. Note that this will override
4132 the short option
4133 short - Short, less verbose, version of configurations.
4134 This is overridden by the json option
4135 returns:
4136 Output from cli as a string or None on error
4137 """
4138 try:
4139 baseStr = "cfg"
4140 cmdStr = " get"
4141 componentStr = ""
4142 if component:
4143 componentStr += " " + component
4144 if propName:
4145 componentStr += " " + propName
4146 if jsonFormat:
4147 baseStr += " -j"
4148 elif short:
4149 baseStr += " -s"
4150 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004151 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004152 assert "Command not found:" not in output, output
4153 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004154 return output
4155 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004156 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004157 return None
4158 except TypeError:
4159 main.log.exception( self.name + ": Object not as expected" )
4160 return None
4161 except pexpect.EOF:
4162 main.log.error( self.name + ": EOF exception found" )
4163 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004164 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004165 except Exception:
4166 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004167 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004168
4169 def setCfg( self, component, propName, value=None, check=True ):
4170 """
4171 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004172 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004173 component - The case sensitive name of the component whose
4174 property is to be set
4175 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004176 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004177 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004178 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004179 check - Boolean, Check whether the option was successfully set this
4180 only applies when a value is given.
4181 returns:
4182 main.TRUE on success or main.FALSE on failure. If check is False,
4183 will return main.TRUE unless there is an error
4184 """
4185 try:
4186 baseStr = "cfg"
4187 cmdStr = " set " + str( component ) + " " + str( propName )
4188 if value is not None:
4189 cmdStr += " " + str( value )
4190 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004191 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004192 assert "Command not found:" not in output, output
4193 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004194 if value and check:
4195 results = self.getCfg( component=str( component ),
4196 propName=str( propName ),
4197 jsonFormat=True )
4198 # Check if current value is what we just set
4199 try:
4200 jsonOutput = json.loads( results )
4201 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004202 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004203 main.log.exception( "Error parsing cfg output" )
4204 main.log.error( "output:" + repr( results ) )
4205 return main.FALSE
4206 if current == str( value ):
4207 return main.TRUE
4208 return main.FALSE
4209 return main.TRUE
4210 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004211 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004212 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004213 except ( TypeError, ValueError ):
4214 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004215 return main.FALSE
4216 except pexpect.EOF:
4217 main.log.error( self.name + ": EOF exception found" )
4218 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004219 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004220 except Exception:
4221 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004222 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004223
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004224 def distPrimitivesSend( self, cmd ):
4225 """
4226 Function to handle sending cli commands for the distributed primitives test app
4227
4228 This command will catch some exceptions and retry the command on some
4229 specific store exceptions.
4230
4231 Required arguments:
4232 cmd - The command to send to the cli
4233 returns:
4234 string containing the cli output
4235 None on Error
4236 """
4237 try:
4238 output = self.sendline( cmd )
4239 try:
4240 assert output is not None, "Error in sendline"
4241 # TODO: Maybe make this less hardcoded
4242 # ConsistentMap Exceptions
4243 assert "org.onosproject.store.service" not in output
4244 # Node not leader
4245 assert "java.lang.IllegalStateException" not in output
4246 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004247 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004248 "command: " + str( output ) )
4249 retryTime = 30 # Conservative time, given by Madan
4250 main.log.info( "Waiting " + str( retryTime ) +
4251 "seconds before retrying." )
4252 time.sleep( retryTime ) # Due to change in mastership
4253 output = self.sendline( cmd )
4254 assert output is not None, "Error in sendline"
4255 assert "Command not found:" not in output, output
4256 assert "Error executing command" not in output, output
4257 main.log.info( self.name + ": " + output )
4258 return output
4259 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004260 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004261 return None
4262 except TypeError:
4263 main.log.exception( self.name + ": Object not as expected" )
4264 return None
4265 except pexpect.EOF:
4266 main.log.error( self.name + ": EOF exception found" )
4267 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004268 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004269 except Exception:
4270 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004271 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004272
Jon Hall390696c2015-05-05 17:13:41 -07004273 def setTestAdd( self, setName, values ):
4274 """
4275 CLI command to add elements to a distributed set.
4276 Arguments:
4277 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004278 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004279 Example usages:
4280 setTestAdd( "set1", "a b c" )
4281 setTestAdd( "set2", "1" )
4282 returns:
4283 main.TRUE on success OR
4284 main.FALSE if elements were already in the set OR
4285 main.ERROR on error
4286 """
4287 try:
4288 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004289 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004290 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4291 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004292 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004293 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004294 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004295 return main.FALSE
4296 else:
4297 main.log.error( self.name + ": setTestAdd did not" +
4298 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004299 main.log.debug( self.name + " actual: " + repr( output ) )
4300 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004301 except TypeError:
4302 main.log.exception( self.name + ": Object not as expected" )
4303 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004304 except Exception:
4305 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004306 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004307
4308 def setTestRemove( self, setName, values, clear=False, retain=False ):
4309 """
4310 CLI command to remove elements from a distributed set.
4311 Required arguments:
4312 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004313 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004314 Optional arguments:
4315 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004316 retain - Retain only the given values. (intersection of the
4317 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004318 returns:
4319 main.TRUE on success OR
4320 main.FALSE if the set was not changed OR
4321 main.ERROR on error
4322 """
4323 try:
4324 cmdStr = "set-test-remove "
4325 if clear:
4326 cmdStr += "-c " + str( setName )
4327 elif retain:
4328 cmdStr += "-r " + str( setName ) + " " + str( values )
4329 else:
4330 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004331 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004332 if clear:
4333 pattern = "Set " + str( setName ) + " cleared"
4334 if re.search( pattern, output ):
4335 return main.TRUE
4336 elif retain:
4337 positivePattern = str( setName ) + " was pruned to contain " +\
4338 "only elements of set \[(.*)\]"
4339 negativePattern = str( setName ) + " was not changed by " +\
4340 "retaining only elements of the set " +\
4341 "\[(.*)\]"
4342 if re.search( positivePattern, output ):
4343 return main.TRUE
4344 elif re.search( negativePattern, output ):
4345 return main.FALSE
4346 else:
4347 positivePattern = "\[(.*)\] was removed from the set " +\
4348 str( setName )
4349 if ( len( values.split() ) == 1 ):
4350 negativePattern = "\[(.*)\] was not in set " +\
4351 str( setName )
4352 else:
4353 negativePattern = "No element of \[(.*)\] was in set " +\
4354 str( setName )
4355 if re.search( positivePattern, output ):
4356 return main.TRUE
4357 elif re.search( negativePattern, output ):
4358 return main.FALSE
4359 main.log.error( self.name + ": setTestRemove 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 main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004364 except TypeError:
4365 main.log.exception( self.name + ": Object not as expected" )
4366 return main.ERROR
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
4371 def setTestGet( self, setName, values="" ):
4372 """
4373 CLI command to get the elements in a distributed set.
4374 Required arguments:
4375 setName - The name of the set to remove from.
4376 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004377 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004378 returns:
4379 main.ERROR on error OR
4380 A list of elements in the set if no optional arguments are
4381 supplied OR
4382 A tuple containing the list then:
4383 main.FALSE if the given values are not in the set OR
4384 main.TRUE if the given values are in the set OR
4385 """
4386 try:
4387 values = str( values ).strip()
4388 setName = str( setName ).strip()
4389 length = len( values.split() )
4390 containsCheck = None
4391 # Patterns to match
4392 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004393 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004394 containsTrue = "Set " + setName + " contains the value " + values
4395 containsFalse = "Set " + setName + " did not contain the value " +\
4396 values
4397 containsAllTrue = "Set " + setName + " contains the the subset " +\
4398 setPattern
4399 containsAllFalse = "Set " + setName + " did not contain the the" +\
4400 " subset " + setPattern
4401
4402 cmdStr = "set-test-get "
4403 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004404 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004405 if length == 0:
4406 match = re.search( pattern, output )
4407 else: # if given values
4408 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004409 patternTrue = pattern + "\r\n" + containsTrue
4410 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004411 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004412 patternTrue = pattern + "\r\n" + containsAllTrue
4413 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004414 matchTrue = re.search( patternTrue, output )
4415 matchFalse = re.search( patternFalse, output )
4416 if matchTrue:
4417 containsCheck = main.TRUE
4418 match = matchTrue
4419 elif matchFalse:
4420 containsCheck = main.FALSE
4421 match = matchFalse
4422 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004423 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004424 "expected output" )
4425 main.log.debug( self.name + " expected: " + pattern )
4426 main.log.debug( self.name + " actual: " + repr( output ) )
4427 match = None
4428 if match:
4429 setMatch = match.group( 1 )
4430 if setMatch == '':
4431 setList = []
4432 else:
4433 setList = setMatch.split( ", " )
4434 if length > 0:
4435 return ( setList, containsCheck )
4436 else:
4437 return setList
4438 else: # no match
4439 main.log.error( self.name + ": setTestGet did not" +
4440 " match expected output" )
4441 main.log.debug( self.name + " expected: " + pattern )
4442 main.log.debug( self.name + " actual: " + repr( output ) )
4443 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004444 except TypeError:
4445 main.log.exception( self.name + ": Object not as expected" )
4446 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004447 except Exception:
4448 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004449 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004450
4451 def setTestSize( self, setName ):
4452 """
4453 CLI command to get the elements in a distributed set.
4454 Required arguments:
4455 setName - The name of the set to remove from.
4456 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004457 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004458 None on error
4459 """
4460 try:
4461 # TODO: Should this check against the number of elements returned
4462 # and then return true/false based on that?
4463 setName = str( setName ).strip()
4464 # Patterns to match
4465 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004466 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004467 setPattern
4468 cmdStr = "set-test-get -s "
4469 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004470 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004471 if output:
4472 match = re.search( pattern, output )
4473 if match:
4474 setSize = int( match.group( 1 ) )
4475 setMatch = match.group( 2 )
4476 if len( setMatch.split() ) == setSize:
4477 main.log.info( "The size returned by " + self.name +
4478 " matches the number of elements in " +
4479 "the returned set" )
4480 else:
4481 main.log.error( "The size returned by " + self.name +
4482 " does not match the number of " +
4483 "elements in the returned set." )
4484 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004485 else: # no match
4486 main.log.error( self.name + ": setTestGet did not" +
4487 " match expected output" )
4488 main.log.debug( self.name + " expected: " + pattern )
4489 main.log.debug( self.name + " actual: " + repr( output ) )
4490 return None
Jon Hall390696c2015-05-05 17:13:41 -07004491 except TypeError:
4492 main.log.exception( self.name + ": Object not as expected" )
4493 return None
Jon Hall390696c2015-05-05 17:13:41 -07004494 except Exception:
4495 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004496 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004497
Jon Hall80daded2015-05-27 16:07:00 -07004498 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004499 """
4500 Command to list the various counters in the system.
4501 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004502 if jsonFormat, a string of the json object returned by the cli
4503 command
4504 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004505 None on error
4506 """
Jon Hall390696c2015-05-05 17:13:41 -07004507 try:
Jon Hall390696c2015-05-05 17:13:41 -07004508 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004509 if jsonFormat:
4510 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004511 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004512 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004513 assert "Command not found:" not in output, output
4514 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004515 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004516 return output
Jon Hall390696c2015-05-05 17:13:41 -07004517 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004518 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004519 return None
Jon Hall390696c2015-05-05 17:13:41 -07004520 except TypeError:
4521 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004522 return None
Jon Hall390696c2015-05-05 17:13:41 -07004523 except pexpect.EOF:
4524 main.log.error( self.name + ": EOF exception found" )
4525 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004526 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004527 except Exception:
4528 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004529 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004530
Jon Hall935db192016-04-19 00:22:04 -07004531 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004532 """
Jon Halle1a3b752015-07-22 13:02:46 -07004533 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004534 Required arguments:
4535 counter - The name of the counter to increment.
4536 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004537 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004538 returns:
4539 integer value of the counter or
4540 None on Error
4541 """
4542 try:
4543 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004544 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004545 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004546 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004547 if delta != 1:
4548 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004549 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004550 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004551 match = re.search( pattern, output )
4552 if match:
4553 return int( match.group( 1 ) )
4554 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004555 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004556 " match expected output." )
4557 main.log.debug( self.name + " expected: " + pattern )
4558 main.log.debug( self.name + " actual: " + repr( output ) )
4559 return None
Jon Hall390696c2015-05-05 17:13:41 -07004560 except TypeError:
4561 main.log.exception( self.name + ": Object not as expected" )
4562 return None
Jon Hall390696c2015-05-05 17:13:41 -07004563 except Exception:
4564 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004565 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004566
Jon Hall935db192016-04-19 00:22:04 -07004567 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004568 """
4569 CLI command to get a distributed counter then add a delta to it.
4570 Required arguments:
4571 counter - The name of the counter to increment.
4572 Optional arguments:
4573 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004574 returns:
4575 integer value of the counter or
4576 None on Error
4577 """
4578 try:
4579 counter = str( counter )
4580 delta = int( delta )
4581 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004582 cmdStr += counter
4583 if delta != 1:
4584 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004585 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004586 pattern = counter + " was updated to (-?\d+)"
4587 match = re.search( pattern, output )
4588 if match:
4589 return int( match.group( 1 ) )
4590 else:
4591 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4592 " match expected output." )
4593 main.log.debug( self.name + " expected: " + pattern )
4594 main.log.debug( self.name + " actual: " + repr( output ) )
4595 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004596 except TypeError:
4597 main.log.exception( self.name + ": Object not as expected" )
4598 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004599 except Exception:
4600 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004601 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004602
4603 def valueTestGet( self, valueName ):
4604 """
4605 CLI command to get the value of an atomic value.
4606 Required arguments:
4607 valueName - The name of the value to get.
4608 returns:
4609 string value of the value or
4610 None on Error
4611 """
4612 try:
4613 valueName = str( valueName )
4614 cmdStr = "value-test "
4615 operation = "get"
4616 cmdStr = "value-test {} {}".format( valueName,
4617 operation )
4618 output = self.distPrimitivesSend( cmdStr )
4619 pattern = "(\w+)"
4620 match = re.search( pattern, output )
4621 if match:
4622 return match.group( 1 )
4623 else:
4624 main.log.error( self.name + ": valueTestGet did not" +
4625 " match expected output." )
4626 main.log.debug( self.name + " expected: " + pattern )
4627 main.log.debug( self.name + " actual: " + repr( output ) )
4628 return None
4629 except TypeError:
4630 main.log.exception( self.name + ": Object not as expected" )
4631 return None
4632 except Exception:
4633 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004634 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004635
4636 def valueTestSet( self, valueName, newValue ):
4637 """
4638 CLI command to set the value of an atomic value.
4639 Required arguments:
4640 valueName - The name of the value to set.
4641 newValue - The value to assign to the given value.
4642 returns:
4643 main.TRUE on success or
4644 main.ERROR on Error
4645 """
4646 try:
4647 valueName = str( valueName )
4648 newValue = str( newValue )
4649 operation = "set"
4650 cmdStr = "value-test {} {} {}".format( valueName,
4651 operation,
4652 newValue )
4653 output = self.distPrimitivesSend( cmdStr )
4654 if output is not None:
4655 return main.TRUE
4656 else:
4657 return main.ERROR
4658 except TypeError:
4659 main.log.exception( self.name + ": Object not as expected" )
4660 return main.ERROR
4661 except Exception:
4662 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004663 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004664
4665 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4666 """
4667 CLI command to compareAndSet the value of an atomic value.
4668 Required arguments:
4669 valueName - The name of the value.
4670 oldValue - Compare the current value of the atomic value to this
4671 newValue - If the value equals oldValue, set the value to newValue
4672 returns:
4673 main.TRUE on success or
4674 main.FALSE on failure or
4675 main.ERROR on Error
4676 """
4677 try:
4678 valueName = str( valueName )
4679 oldValue = str( oldValue )
4680 newValue = str( newValue )
4681 operation = "compareAndSet"
4682 cmdStr = "value-test {} {} {} {}".format( valueName,
4683 operation,
4684 oldValue,
4685 newValue )
4686 output = self.distPrimitivesSend( cmdStr )
4687 pattern = "(\w+)"
4688 match = re.search( pattern, output )
4689 if match:
4690 result = match.group( 1 )
4691 if result == "true":
4692 return main.TRUE
4693 elif result == "false":
4694 return main.FALSE
4695 else:
4696 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4697 " match expected output." )
4698 main.log.debug( self.name + " expected: " + pattern )
4699 main.log.debug( self.name + " actual: " + repr( output ) )
4700 return main.ERROR
4701 except TypeError:
4702 main.log.exception( self.name + ": Object not as expected" )
4703 return main.ERROR
4704 except Exception:
4705 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004706 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004707
4708 def valueTestGetAndSet( self, valueName, newValue ):
4709 """
4710 CLI command to getAndSet the value of an atomic value.
4711 Required arguments:
4712 valueName - The name of the value to get.
4713 newValue - The value to assign to the given value
4714 returns:
4715 string value of the value or
4716 None on Error
4717 """
4718 try:
4719 valueName = str( valueName )
4720 cmdStr = "value-test "
4721 operation = "getAndSet"
4722 cmdStr += valueName + " " + operation
4723 cmdStr = "value-test {} {} {}".format( valueName,
4724 operation,
4725 newValue )
4726 output = self.distPrimitivesSend( cmdStr )
4727 pattern = "(\w+)"
4728 match = re.search( pattern, output )
4729 if match:
4730 return match.group( 1 )
4731 else:
4732 main.log.error( self.name + ": valueTestGetAndSet did not" +
4733 " match expected output." )
4734 main.log.debug( self.name + " expected: " + pattern )
4735 main.log.debug( self.name + " actual: " + repr( output ) )
4736 return None
4737 except TypeError:
4738 main.log.exception( self.name + ": Object not as expected" )
4739 return None
4740 except Exception:
4741 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004742 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004743
4744 def valueTestDestroy( self, valueName ):
4745 """
4746 CLI command to destroy an atomic value.
4747 Required arguments:
4748 valueName - The name of the value to destroy.
4749 returns:
4750 main.TRUE on success or
4751 main.ERROR on Error
4752 """
4753 try:
4754 valueName = str( valueName )
4755 cmdStr = "value-test "
4756 operation = "destroy"
4757 cmdStr += valueName + " " + operation
4758 output = self.distPrimitivesSend( cmdStr )
4759 if output is not None:
4760 return main.TRUE
4761 else:
4762 return main.ERROR
4763 except TypeError:
4764 main.log.exception( self.name + ": Object not as expected" )
4765 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004766 except Exception:
4767 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004768 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004769
YPZhangfebf7302016-05-24 16:45:56 -07004770 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004771 """
4772 Description: Execute summary command in onos
4773 Returns: json object ( summary -j ), returns main.FALSE if there is
4774 no output
4775
4776 """
4777 try:
4778 cmdStr = "summary"
4779 if jsonFormat:
4780 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004781 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004782 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004783 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004784 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004785 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004786 if not handle:
4787 main.log.error( self.name + ": There is no output in " +
4788 "summary command" )
4789 return main.FALSE
4790 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004791 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004792 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004793 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004794 except TypeError:
4795 main.log.exception( self.name + ": Object not as expected" )
4796 return None
4797 except pexpect.EOF:
4798 main.log.error( self.name + ": EOF exception found" )
4799 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004800 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004801 except Exception:
4802 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004803 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004804
Jon Hall935db192016-04-19 00:22:04 -07004805 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004806 """
4807 CLI command to get the value of a key in a consistent map using
4808 transactions. This a test function and can only get keys from the
4809 test map hard coded into the cli command
4810 Required arguments:
4811 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004812 returns:
4813 The string value of the key or
4814 None on Error
4815 """
4816 try:
4817 keyName = str( keyName )
4818 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004819 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004820 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004821 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4822 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004823 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004824 return None
4825 else:
4826 match = re.search( pattern, output )
4827 if match:
4828 return match.groupdict()[ 'value' ]
4829 else:
4830 main.log.error( self.name + ": transactionlMapGet did not" +
4831 " match expected output." )
4832 main.log.debug( self.name + " expected: " + pattern )
4833 main.log.debug( self.name + " actual: " + repr( output ) )
4834 return None
4835 except TypeError:
4836 main.log.exception( self.name + ": Object not as expected" )
4837 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004838 except Exception:
4839 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004840 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004841
Jon Hall935db192016-04-19 00:22:04 -07004842 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004843 """
4844 CLI command to put a value into 'numKeys' number of keys in a
4845 consistent map using transactions. This a test function and can only
4846 put into keys named 'Key#' of the test map hard coded into the cli command
4847 Required arguments:
4848 numKeys - Number of keys to add the value to
4849 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004850 returns:
4851 A dictionary whose keys are the name of the keys put into the map
4852 and the values of the keys are dictionaries whose key-values are
4853 'value': value put into map and optionaly
4854 'oldValue': Previous value in the key or
4855 None on Error
4856
4857 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004858 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4859 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004860 """
4861 try:
4862 numKeys = str( numKeys )
4863 value = str( value )
4864 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004865 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004866 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004867 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4868 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4869 results = {}
4870 for line in output.splitlines():
4871 new = re.search( newPattern, line )
4872 updated = re.search( updatedPattern, line )
4873 if new:
4874 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4875 elif updated:
4876 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004877 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004878 else:
4879 main.log.error( self.name + ": transactionlMapGet did not" +
4880 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004881 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4882 newPattern,
4883 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004884 main.log.debug( self.name + " actual: " + repr( output ) )
4885 return results
Jon Hall0e240372018-05-02 11:21:57 -07004886 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004887 main.log.exception( self.name + ": Object not as expected" )
4888 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004889 except Exception:
4890 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004891 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004892
acsmarsdaea66c2015-09-03 11:44:06 -07004893 def maps( self, jsonFormat=True ):
4894 """
4895 Description: Returns result of onos:maps
4896 Optional:
4897 * jsonFormat: enable json formatting of output
4898 """
4899 try:
4900 cmdStr = "maps"
4901 if jsonFormat:
4902 cmdStr += " -j"
4903 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004904 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004905 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004906 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004907 except AssertionError:
4908 main.log.exception( "" )
4909 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004910 except TypeError:
4911 main.log.exception( self.name + ": Object not as expected" )
4912 return None
4913 except pexpect.EOF:
4914 main.log.error( self.name + ": EOF exception found" )
4915 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004916 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004917 except Exception:
4918 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004919 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004920
4921 def getSwController( self, uri, jsonFormat=True ):
4922 """
4923 Descrition: Gets the controller information from the device
4924 """
4925 try:
4926 cmd = "device-controllers "
4927 if jsonFormat:
4928 cmd += "-j "
4929 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004930 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004931 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004932 return response
Jon Hallc6793552016-01-19 14:18:37 -08004933 except AssertionError:
4934 main.log.exception( "" )
4935 return None
GlennRC050596c2015-11-18 17:06:41 -08004936 except TypeError:
4937 main.log.exception( self.name + ": Object not as expected" )
4938 return None
4939 except pexpect.EOF:
4940 main.log.error( self.name + ": EOF exception found" )
4941 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004942 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004943 except Exception:
4944 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004945 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004946
4947 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4948 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004949 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004950
4951 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004952 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08004953 ip - String or List: The ip address of the controller.
4954 This parameter can be formed in a couple of different ways.
4955 VALID:
4956 10.0.0.1 - just the ip address
4957 tcp:10.0.0.1 - the protocol and the ip address
4958 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4959 so that you can add controllers with different
4960 protocols and ports
4961 INVALID:
4962 10.0.0.1:6653 - this is not supported by ONOS
4963
4964 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4965 port - The port number.
4966 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4967
4968 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4969 """
4970 try:
4971 cmd = "device-setcontrollers"
4972
4973 if jsonFormat:
4974 cmd += " -j"
4975 cmd += " " + uri
4976 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004977 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08004978 for item in ip:
4979 if ":" in item:
4980 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004981 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08004982 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004983 elif "." in sitem[ 1 ]:
4984 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08004985 else:
4986 main.log.error( "Malformed entry: " + item )
4987 raise TypeError
4988 else:
4989 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004990 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004991 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004992 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004993 if "Error" in response:
4994 main.log.error( response )
4995 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004996 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004997 except AssertionError:
4998 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004999 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005000 except TypeError:
5001 main.log.exception( self.name + ": Object not as expected" )
5002 return main.FALSE
5003 except pexpect.EOF:
5004 main.log.error( self.name + ": EOF exception found" )
5005 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005006 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005007 except Exception:
5008 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005009 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005010
5011 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005012 '''
GlennRC20fc6522015-12-23 23:26:57 -08005013 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005014 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005015 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005016 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005017 Returns:
5018 Returns main.FALSE if an exception is thrown or an error is present
5019 in the response. Otherwise, returns main.TRUE.
5020 NOTE:
5021 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005022 '''
GlennRC20fc6522015-12-23 23:26:57 -08005023 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005024 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005025 deviceStr = device
5026 device = []
5027 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005028
5029 for d in device:
5030 time.sleep( 1 )
5031 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005032 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005033 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005034 if "Error" in response:
5035 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5036 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005037 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005038 except AssertionError:
5039 main.log.exception( "" )
5040 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005041 except TypeError:
5042 main.log.exception( self.name + ": Object not as expected" )
5043 return main.FALSE
5044 except pexpect.EOF:
5045 main.log.error( self.name + ": EOF exception found" )
5046 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005047 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005048 except Exception:
5049 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005050 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005051
5052 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005053 '''
GlennRC20fc6522015-12-23 23:26:57 -08005054 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005055 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005056 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005057 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005058 Returns:
5059 Returns main.FALSE if an exception is thrown or an error is present
5060 in the response. Otherwise, returns main.TRUE.
5061 NOTE:
5062 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005063 '''
GlennRC20fc6522015-12-23 23:26:57 -08005064 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005065 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005066 host = list( host )
5067
5068 for h in host:
5069 time.sleep( 1 )
5070 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005071 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005072 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005073 if "Error" in response:
5074 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5075 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005076 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005077 except AssertionError:
5078 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005079 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005080 except TypeError:
5081 main.log.exception( self.name + ": Object not as expected" )
5082 return main.FALSE
5083 except pexpect.EOF:
5084 main.log.error( self.name + ": EOF exception found" )
5085 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005086 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005087 except Exception:
5088 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005089 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005090
YPZhangfebf7302016-05-24 16:45:56 -07005091 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005092 '''
GlennRCed771242016-01-13 17:02:47 -08005093 Description:
5094 Bring link down or up in the null-provider.
5095 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005096 begin - (string) One end of a device or switch.
5097 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005098 returns:
5099 main.TRUE if no exceptions were thrown and no Errors are
5100 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005101 '''
GlennRCed771242016-01-13 17:02:47 -08005102 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005103 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005104 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005105 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005106 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005107 if "Error" in response or "Failure" in response:
5108 main.log.error( response )
5109 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005110 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005111 except AssertionError:
5112 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005113 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005114 except TypeError:
5115 main.log.exception( self.name + ": Object not as expected" )
5116 return main.FALSE
5117 except pexpect.EOF:
5118 main.log.error( self.name + ": EOF exception found" )
5119 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005120 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005121 except Exception:
5122 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005123 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005124
Jon Hall2c8959e2016-12-16 12:17:34 -08005125 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005126 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005127 Description:
5128 Changes the state of port in an OF switch by means of the
5129 PORTSTATUS OF messages.
5130 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005131 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5132 port - (string) target port in the device. Ex: '2'
5133 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005134 returns:
5135 main.TRUE if no exceptions were thrown and no Errors are
5136 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005137 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005138 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005139 state = state.lower()
5140 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005141 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005142 response = self.sendline( cmd, showResponse=True )
5143 assert response is not None, "Error in sendline"
5144 assert "Command not found:" not in response, response
5145 if "Error" in response or "Failure" in response:
5146 main.log.error( response )
5147 return main.FALSE
5148 return main.TRUE
5149 except AssertionError:
5150 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005151 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005152 except TypeError:
5153 main.log.exception( self.name + ": Object not as expected" )
5154 return main.FALSE
5155 except pexpect.EOF:
5156 main.log.error( self.name + ": EOF exception found" )
5157 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005158 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005159 except Exception:
5160 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005161 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005162
5163 def logSet( self, level="INFO", app="org.onosproject" ):
5164 """
5165 Set the logging level to lvl for a specific app
5166 returns main.TRUE on success
5167 returns main.FALSE if Error occurred
5168 if noExit is True, TestON will not exit, but clean up
5169 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5170 Level defaults to INFO
5171 """
5172 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005173 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005174 self.handle.expect( "onos>" )
5175
5176 response = self.handle.before
5177 if re.search( "Error", response ):
5178 return main.FALSE
5179 return main.TRUE
5180 except pexpect.TIMEOUT:
5181 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005182 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005183 except pexpect.EOF:
5184 main.log.error( self.name + ": EOF exception found" )
5185 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005186 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005187 except Exception:
5188 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005189 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005190
5191 def getGraphDict( self, timeout=60, includeHost=False ):
5192 """
5193 Return a dictionary which describes the latest network topology data as a
5194 graph.
5195 An example of the dictionary:
5196 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5197 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5198 Each vertex should at least have an 'edges' attribute which describes the
5199 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005200 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005201 list of attributes.
5202 An example of the edges dictionary:
5203 'edges': { vertex2: { 'port': ..., 'weight': ... },
5204 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005205 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005206 in topology data.
5207 """
5208 graphDict = {}
5209 try:
5210 links = self.links()
5211 links = json.loads( links )
5212 devices = self.devices()
5213 devices = json.loads( devices )
5214 idToDevice = {}
5215 for device in devices:
5216 idToDevice[ device[ 'id' ] ] = device
5217 if includeHost:
5218 hosts = self.hosts()
5219 # FIXME: support 'includeHost' argument
5220 for link in links:
5221 nodeA = link[ 'src' ][ 'device' ]
5222 nodeB = link[ 'dst' ][ 'device' ]
5223 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005224 if nodeA not in graphDict.keys():
5225 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005226 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005227 'type': idToDevice[ nodeA ][ 'type' ],
5228 'available': idToDevice[ nodeA ][ 'available' ],
5229 'role': idToDevice[ nodeA ][ 'role' ],
5230 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5231 'hw': idToDevice[ nodeA ][ 'hw' ],
5232 'sw': idToDevice[ nodeA ][ 'sw' ],
5233 'serial': idToDevice[ nodeA ][ 'serial' ],
5234 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005235 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005236 else:
5237 # Assert nodeB is not connected to any current links of nodeA
You Wang9fc5ce42019-01-23 15:10:08 -08005238 # assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
5239 pass
Jon Halle0f0b342017-04-18 11:43:47 -07005240 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5241 'type': link[ 'type' ],
5242 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005243 return graphDict
5244 except ( TypeError, ValueError ):
5245 main.log.exception( self.name + ": Object not as expected" )
5246 return None
5247 except KeyError:
5248 main.log.exception( self.name + ": KeyError exception found" )
5249 return None
5250 except AssertionError:
5251 main.log.exception( self.name + ": AssertionError exception found" )
5252 return None
5253 except pexpect.EOF:
5254 main.log.error( self.name + ": EOF exception found" )
5255 main.log.error( self.name + ": " + self.handle.before )
5256 return None
5257 except Exception:
5258 main.log.exception( self.name + ": Uncaught exception!" )
5259 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005260
5261 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005262 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005263 Send command to check intent-perf summary
5264 Returns: dictionary for intent-perf summary
5265 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005266 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005267 cmd = "intent-perf -s"
5268 respDic = {}
5269 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005270 assert resp is not None, "Error in sendline"
5271 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005272 try:
5273 # Generate the dictionary to return
5274 for l in resp.split( "\n" ):
5275 # Delete any white space in line
5276 temp = re.sub( r'\s+', '', l )
5277 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005278 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005279
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005280 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005281 main.log.exception( self.name + ": Object not as expected" )
5282 return None
5283 except KeyError:
5284 main.log.exception( self.name + ": KeyError exception found" )
5285 return None
5286 except AssertionError:
5287 main.log.exception( self.name + ": AssertionError exception found" )
5288 return None
5289 except pexpect.EOF:
5290 main.log.error( self.name + ": EOF exception found" )
5291 main.log.error( self.name + ": " + self.handle.before )
5292 return None
5293 except Exception:
5294 main.log.exception( self.name + ": Uncaught exception!" )
5295 return None
5296 return respDic
5297
Chiyu Chengec63bde2016-11-17 18:11:36 -08005298 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005299 """
5300 Searches the latest ONOS log file for the given search term and
5301 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005302
chengchiyu08303a02016-09-08 17:40:26 -07005303 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005304 searchTerm:
5305 The string to grep from the ONOS log.
5306 startLine:
5307 The term that decides which line is the start to search the searchTerm in
5308 the karaf log. For now, startTerm only works in 'first' mode.
5309 logNum:
5310 In some extreme cases, one karaf log is not big enough to contain all the
5311 information.Because of this, search mutiply logs is necessary to capture
5312 the right result. logNum is the number of karaf logs that we need to search
5313 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005314 mode:
5315 all: return all the strings that contain the search term
5316 last: return the last string that contains the search term
5317 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005318 num: return the number of times that the searchTerm appears in the log
5319 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005320 """
5321 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005322 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005323 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005324 logPath = '/opt/onos/log/karaf.log.'
5325 logPaths = '/opt/onos/log/karaf.log'
5326 for i in range( 1, logNum ):
5327 logPaths = logPath + str( i ) + " " + logPaths
5328 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005329 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005330 # 100000000 is just a extreme large number to make sure this function can
5331 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005332 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005333 if mode == 'all':
5334 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005335 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005336 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005337 elif mode == 'first':
5338 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5339 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005340 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005341 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005342 return num
You Wang6d301d42017-04-21 10:49:33 -07005343 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005344 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005345 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005346 else:
5347 main.log.error( self.name + " unsupported mode" )
5348 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005349 before = self.sendline( cmd )
5350 before = before.splitlines()
5351 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005352 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005353 return returnLines
5354 except AssertionError:
5355 main.log.error( self.name + " searchTerm is not string type" )
5356 return None
5357 except pexpect.EOF:
5358 main.log.error( self.name + ": EOF exception found" )
5359 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005360 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005361 except pexpect.TIMEOUT:
5362 main.log.error( self.name + ": TIMEOUT exception found" )
5363 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005364 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005365 except Exception:
5366 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005367 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005368
5369 def vplsShow( self, jsonFormat=True ):
5370 """
5371 Description: Returns result of onos:vpls show, which should list the
5372 configured VPLS networks and the assigned interfaces.
5373 Optional:
5374 * jsonFormat: enable json formatting of output
5375 Returns:
5376 The output of the command or None on error.
5377 """
5378 try:
5379 cmdStr = "vpls show"
5380 if jsonFormat:
5381 raise NotImplementedError
5382 cmdStr += " -j"
5383 handle = self.sendline( cmdStr )
5384 assert handle is not None, "Error in sendline"
5385 assert "Command not found:" not in handle, handle
5386 return handle
5387 except AssertionError:
5388 main.log.exception( "" )
5389 return None
5390 except TypeError:
5391 main.log.exception( self.name + ": Object not as expected" )
5392 return None
5393 except pexpect.EOF:
5394 main.log.error( self.name + ": EOF exception found" )
5395 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005396 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005397 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005398 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005399 return None
5400 except Exception:
5401 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005402 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005403
5404 def parseVplsShow( self ):
5405 """
5406 Parse the cli output of 'vpls show' into json output. This is required
5407 as there is currently no json output available.
5408 """
5409 try:
5410 output = []
5411 raw = self.vplsShow( jsonFormat=False )
5412 namePat = "VPLS name: (?P<name>\w+)"
5413 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5414 encapPat = "Encapsulation: (?P<encap>\w+)"
5415 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5416 mIter = re.finditer( pattern, raw )
5417 for match in mIter:
5418 item = {}
5419 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005420 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005421 if ifaces == [ "" ]:
5422 ifaces = []
5423 item[ 'interfaces' ] = ifaces
5424 encap = match.group( 'encap' )
5425 if encap != 'NONE':
5426 item[ 'encapsulation' ] = encap.lower()
5427 output.append( item )
5428 return output
5429 except Exception:
5430 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005431 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005432
5433 def vplsList( self, jsonFormat=True ):
5434 """
5435 Description: Returns result of onos:vpls list, which should list the
5436 configured VPLS networks.
5437 Optional:
5438 * jsonFormat: enable json formatting of output
5439 """
5440 try:
5441 cmdStr = "vpls list"
5442 if jsonFormat:
5443 raise NotImplementedError
5444 cmdStr += " -j"
5445 handle = self.sendline( cmdStr )
5446 assert handle is not None, "Error in sendline"
5447 assert "Command not found:" not in handle, handle
5448 return handle
5449 except AssertionError:
5450 main.log.exception( "" )
5451 return None
5452 except TypeError:
5453 main.log.exception( self.name + ": Object not as expected" )
5454 return None
5455 except pexpect.EOF:
5456 main.log.error( self.name + ": EOF exception found" )
5457 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005458 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005459 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005460 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005461 return None
5462 except Exception:
5463 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005464 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005465
5466 def vplsCreate( self, network ):
5467 """
5468 CLI command to create a new VPLS network.
5469 Required arguments:
5470 network - String name of the network to create.
5471 returns:
5472 main.TRUE on success and main.FALSE on failure
5473 """
5474 try:
5475 network = str( network )
5476 cmdStr = "vpls create "
5477 cmdStr += network
5478 output = self.sendline( cmdStr )
5479 assert output is not None, "Error in sendline"
5480 assert "Command not found:" not in output, output
5481 assert "Error executing command" not in output, output
5482 assert "VPLS already exists:" not in output, output
5483 return main.TRUE
5484 except AssertionError:
5485 main.log.exception( "" )
5486 return main.FALSE
5487 except TypeError:
5488 main.log.exception( self.name + ": Object not as expected" )
5489 return main.FALSE
5490 except pexpect.EOF:
5491 main.log.error( self.name + ": EOF exception found" )
5492 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005493 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005494 except Exception:
5495 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005496 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005497
5498 def vplsDelete( self, network ):
5499 """
5500 CLI command to delete a VPLS network.
5501 Required arguments:
5502 network - Name of the network to delete.
5503 returns:
5504 main.TRUE on success and main.FALSE on failure
5505 """
5506 try:
5507 network = str( network )
5508 cmdStr = "vpls delete "
5509 cmdStr += network
5510 output = self.sendline( cmdStr )
5511 assert output is not None, "Error in sendline"
5512 assert "Command not found:" not in output, output
5513 assert "Error executing command" not in output, output
5514 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005515 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005516 return main.TRUE
5517 except AssertionError:
5518 main.log.exception( "" )
5519 return main.FALSE
5520 except TypeError:
5521 main.log.exception( self.name + ": Object not as expected" )
5522 return main.FALSE
5523 except pexpect.EOF:
5524 main.log.error( self.name + ": EOF exception found" )
5525 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005526 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005527 except Exception:
5528 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005529 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005530
5531 def vplsAddIface( self, network, iface ):
5532 """
5533 CLI command to add an interface to a VPLS network.
5534 Required arguments:
5535 network - Name of the network to add the interface to.
5536 iface - The ONOS name for an interface.
5537 returns:
5538 main.TRUE on success and main.FALSE on failure
5539 """
5540 try:
5541 network = str( network )
5542 iface = str( iface )
5543 cmdStr = "vpls add-if "
5544 cmdStr += network + " " + iface
5545 output = self.sendline( cmdStr )
5546 assert output is not None, "Error in sendline"
5547 assert "Command not found:" not in output, output
5548 assert "Error executing command" not in output, output
5549 assert "already associated to network" not in output, output
5550 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005551 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005552 return main.TRUE
5553 except AssertionError:
5554 main.log.exception( "" )
5555 return main.FALSE
5556 except TypeError:
5557 main.log.exception( self.name + ": Object not as expected" )
5558 return main.FALSE
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 Exception:
5564 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005565 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005566
5567 def vplsRemIface( self, network, iface ):
5568 """
5569 CLI command to remove an interface from a VPLS network.
5570 Required arguments:
5571 network - Name of the network to remove the interface from.
5572 iface - Name of the interface to remove.
5573 returns:
5574 main.TRUE on success and main.FALSE on failure
5575 """
5576 try:
5577 iface = str( iface )
5578 cmdStr = "vpls rem-if "
5579 cmdStr += network + " " + iface
5580 output = self.sendline( cmdStr )
5581 assert output is not None, "Error in sendline"
5582 assert "Command not found:" not in output, output
5583 assert "Error executing command" not in output, output
5584 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005585 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005586 return main.TRUE
5587 except AssertionError:
5588 main.log.exception( "" )
5589 return main.FALSE
5590 except TypeError:
5591 main.log.exception( self.name + ": Object not as expected" )
5592 return main.FALSE
5593 except pexpect.EOF:
5594 main.log.error( self.name + ": EOF exception found" )
5595 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005596 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005597 except Exception:
5598 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005599 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005600
5601 def vplsClean( self ):
5602 """
5603 Description: Clears the VPLS app configuration.
5604 Returns: main.TRUE on success and main.FALSE on failure
5605 """
5606 try:
5607 cmdStr = "vpls clean"
5608 handle = self.sendline( cmdStr )
5609 assert handle is not None, "Error in sendline"
5610 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005611 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005612 return handle
5613 except AssertionError:
5614 main.log.exception( "" )
5615 return main.FALSE
5616 except TypeError:
5617 main.log.exception( self.name + ": Object not as expected" )
5618 return main.FALSE
5619 except pexpect.EOF:
5620 main.log.error( self.name + ": EOF exception found" )
5621 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005622 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005623 except Exception:
5624 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005625 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005626
5627 def vplsSetEncap( self, network, encapType ):
5628 """
5629 CLI command to add an interface to a VPLS network.
5630 Required arguments:
5631 network - Name of the network to create.
5632 encapType - Type of encapsulation.
5633 returns:
5634 main.TRUE on success and main.FALSE on failure
5635 """
5636 try:
5637 network = str( network )
5638 encapType = str( encapType ).upper()
5639 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5640 cmdStr = "vpls set-encap "
5641 cmdStr += network + " " + encapType
5642 output = self.sendline( cmdStr )
5643 assert output is not None, "Error in sendline"
5644 assert "Command not found:" not in output, output
5645 assert "Error executing command" not in output, output
5646 assert "already associated to network" not in output, output
5647 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005648 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005649 return main.TRUE
5650 except AssertionError:
5651 main.log.exception( "" )
5652 return main.FALSE
5653 except TypeError:
5654 main.log.exception( self.name + ": Object not as expected" )
5655 return main.FALSE
5656 except pexpect.EOF:
5657 main.log.error( self.name + ": EOF exception found" )
5658 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005659 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005660 except Exception:
5661 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005662 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005663
5664 def interfaces( self, jsonFormat=True ):
5665 """
5666 Description: Returns result of interfaces command.
5667 Optional:
5668 * jsonFormat: enable json formatting of output
5669 Returns:
5670 The output of the command or None on error.
5671 """
5672 try:
5673 cmdStr = "interfaces"
5674 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005675 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005676 cmdStr += " -j"
5677 handle = self.sendline( cmdStr )
5678 assert handle is not None, "Error in sendline"
5679 assert "Command not found:" not in handle, handle
5680 return handle
5681 except AssertionError:
5682 main.log.exception( "" )
5683 return None
5684 except TypeError:
5685 main.log.exception( self.name + ": Object not as expected" )
5686 return None
5687 except pexpect.EOF:
5688 main.log.error( self.name + ": EOF exception found" )
5689 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005690 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005691 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005692 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005693 return None
5694 except Exception:
5695 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005696 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005697
5698 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005699 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005700 Get the timestamp of searchTerm from karaf log.
5701
5702 Arguments:
5703 splitTerm_before and splitTerm_after:
5704
5705 The terms that split the string that contains the timeStamp of
5706 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5707 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5708 and the splitTerm_after is "x"
5709
5710 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005711 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005712 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005713 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005714 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005715 return main.ERROR
5716 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005717 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005718 main.log.warn( "Captured timestamp string is empty" )
5719 return main.ERROR
5720 lines = lines[ 0 ]
5721 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005722 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005723 # get the target value
5724 line = lines.split( splitTerm_before )
5725 key = line[ 1 ].split( splitTerm_after )
5726 return int( key[ 0 ] )
5727 except IndexError:
5728 main.log.warn( "Index Error!" )
5729 return main.ERROR
5730 except AssertionError:
5731 main.log.warn( "Search Term Not Found " )
5732 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005733
5734 def workQueueAdd( self, queueName, value ):
5735 """
5736 CLI command to add a string to the specified Work Queue.
5737 This function uses the distributed primitives test app, which
5738 gives some cli access to distributed primitives for testing
5739 purposes only.
5740
5741 Required arguments:
5742 queueName - The name of the queue to add to
5743 value - The value to add to the queue
5744 returns:
5745 main.TRUE on success, main.FALSE on failure and
5746 main.ERROR on error.
5747 """
5748 try:
5749 queueName = str( queueName )
5750 value = str( value )
5751 prefix = "work-queue-test"
5752 operation = "add"
5753 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5754 output = self.distPrimitivesSend( cmdStr )
5755 if "Invalid operation name" in output:
5756 main.log.warn( output )
5757 return main.ERROR
5758 elif "Done" in output:
5759 return main.TRUE
5760 except TypeError:
5761 main.log.exception( self.name + ": Object not as expected" )
5762 return main.ERROR
5763 except Exception:
5764 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005765 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005766
5767 def workQueueAddMultiple( self, queueName, value1, value2 ):
5768 """
5769 CLI command to add two strings to the specified Work Queue.
5770 This function uses the distributed primitives test app, which
5771 gives some cli access to distributed primitives for testing
5772 purposes only.
5773
5774 Required arguments:
5775 queueName - The name of the queue to add to
5776 value1 - The first value to add to the queue
5777 value2 - The second value to add to the queue
5778 returns:
5779 main.TRUE on success, main.FALSE on failure and
5780 main.ERROR on error.
5781 """
5782 try:
5783 queueName = str( queueName )
5784 value1 = str( value1 )
5785 value2 = str( value2 )
5786 prefix = "work-queue-test"
5787 operation = "addMultiple"
5788 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5789 output = self.distPrimitivesSend( cmdStr )
5790 if "Invalid operation name" in output:
5791 main.log.warn( output )
5792 return main.ERROR
5793 elif "Done" in output:
5794 return main.TRUE
5795 except TypeError:
5796 main.log.exception( self.name + ": Object not as expected" )
5797 return main.ERROR
5798 except Exception:
5799 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005800 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005801
5802 def workQueueTakeAndComplete( self, queueName, number=1 ):
5803 """
5804 CLI command to take a value from the specified Work Queue and compelte it.
5805 This function uses the distributed primitives test app, which
5806 gives some cli access to distributed primitives for testing
5807 purposes only.
5808
5809 Required arguments:
5810 queueName - The name of the queue to add to
5811 number - The number of items to take and complete
5812 returns:
5813 main.TRUE on success, main.FALSE on failure and
5814 main.ERROR on error.
5815 """
5816 try:
5817 queueName = str( queueName )
5818 number = str( int( number ) )
5819 prefix = "work-queue-test"
5820 operation = "takeAndComplete"
5821 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5822 output = self.distPrimitivesSend( cmdStr )
5823 if "Invalid operation name" in output:
5824 main.log.warn( output )
5825 return main.ERROR
5826 elif "Done" in output:
5827 return main.TRUE
5828 except TypeError:
5829 main.log.exception( self.name + ": Object not as expected" )
5830 return main.ERROR
5831 except Exception:
5832 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005833 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005834
5835 def workQueueDestroy( self, queueName ):
5836 """
5837 CLI command to destroy the specified Work Queue.
5838 This function uses the distributed primitives test app, which
5839 gives some cli access to distributed primitives for testing
5840 purposes only.
5841
5842 Required arguments:
5843 queueName - The name of the queue to add to
5844 returns:
5845 main.TRUE on success, main.FALSE on failure and
5846 main.ERROR on error.
5847 """
5848 try:
5849 queueName = str( queueName )
5850 prefix = "work-queue-test"
5851 operation = "destroy"
5852 cmdStr = " ".join( [ prefix, queueName, operation ] )
5853 output = self.distPrimitivesSend( cmdStr )
5854 if "Invalid operation name" in output:
5855 main.log.warn( output )
5856 return main.ERROR
5857 return main.TRUE
5858 except TypeError:
5859 main.log.exception( self.name + ": Object not as expected" )
5860 return main.ERROR
5861 except Exception:
5862 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005863 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005864
5865 def workQueueTotalPending( self, queueName ):
5866 """
5867 CLI command to get the Total Pending items of the specified Work Queue.
5868 This function uses the distributed primitives test app, which
5869 gives some cli access to distributed primitives for testing
5870 purposes only.
5871
5872 Required arguments:
5873 queueName - The name of the queue to add to
5874 returns:
5875 The number of Pending items in the specified work queue or
5876 None on error
5877 """
5878 try:
5879 queueName = str( queueName )
5880 prefix = "work-queue-test"
5881 operation = "totalPending"
5882 cmdStr = " ".join( [ prefix, queueName, operation ] )
5883 output = self.distPrimitivesSend( cmdStr )
5884 pattern = r'\d+'
5885 if "Invalid operation name" in output:
5886 main.log.warn( output )
5887 return None
5888 else:
5889 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005890 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005891 except ( AttributeError, TypeError ):
5892 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5893 return None
5894 except Exception:
5895 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005896 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005897
5898 def workQueueTotalCompleted( self, queueName ):
5899 """
5900 CLI command to get the Total Completed items of the specified Work Queue.
5901 This function uses the distributed primitives test app, which
5902 gives some cli access to distributed primitives for testing
5903 purposes only.
5904
5905 Required arguments:
5906 queueName - The name of the queue to add to
5907 returns:
5908 The number of complete items in the specified work queue or
5909 None on error
5910 """
5911 try:
5912 queueName = str( queueName )
5913 prefix = "work-queue-test"
5914 operation = "totalCompleted"
5915 cmdStr = " ".join( [ prefix, queueName, operation ] )
5916 output = self.distPrimitivesSend( cmdStr )
5917 pattern = r'\d+'
5918 if "Invalid operation name" in output:
5919 main.log.warn( output )
5920 return None
5921 else:
5922 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005923 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005924 except ( AttributeError, TypeError ):
5925 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5926 return None
5927 except Exception:
5928 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005929 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005930
5931 def workQueueTotalInProgress( self, queueName ):
5932 """
5933 CLI command to get the Total In Progress items of the specified Work Queue.
5934 This function uses the distributed primitives test app, which
5935 gives some cli access to distributed primitives for testing
5936 purposes only.
5937
5938 Required arguments:
5939 queueName - The name of the queue to add to
5940 returns:
5941 The number of In Progress items in the specified work queue or
5942 None on error
5943 """
5944 try:
5945 queueName = str( queueName )
5946 prefix = "work-queue-test"
5947 operation = "totalInProgress"
5948 cmdStr = " ".join( [ prefix, queueName, operation ] )
5949 output = self.distPrimitivesSend( cmdStr )
5950 pattern = r'\d+'
5951 if "Invalid operation name" in output:
5952 main.log.warn( output )
5953 return None
5954 else:
5955 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005956 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005957 except ( AttributeError, TypeError ):
5958 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5959 return None
5960 except Exception:
5961 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005962 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005963
5964 def events( self, args='-a' ):
5965 """
5966 Description: Returns events -a command output
5967 Optional:
5968 add other arguments
5969 """
5970 try:
5971 cmdStr = "events"
5972 if args:
5973 cmdStr += " " + args
5974 handle = self.sendline( cmdStr )
5975 assert handle is not None, "Error in sendline"
5976 assert "Command not found:" not in handle, handle
5977 return handle
5978 except AssertionError:
5979 main.log.exception( "" )
5980 return None
5981 except TypeError:
5982 main.log.exception( self.name + ": Object not as expected" )
5983 return None
5984 except pexpect.EOF:
5985 main.log.error( self.name + ": EOF exception found" )
5986 main.log.error( self.name + ": " + self.handle.before )
5987 main.cleanAndExit()
5988 except Exception:
5989 main.log.exception( self.name + ": Uncaught exception!" )
5990 main.cleanAndExit()
5991
5992 def getMaster( self, deviceID ):
5993 """
5994 Description: Obtains current master using "roles" command for a specific deviceID
5995 """
5996 try:
5997 return str( self.getRole( deviceID )[ 'master' ] )
5998 except AssertionError:
5999 main.log.exception( "" )
6000 return None
6001 except TypeError:
6002 main.log.exception( self.name + ": Object not as expected" )
6003 return None
6004 except pexpect.EOF:
6005 main.log.error( self.name + ": EOF exception found" )
6006 main.log.error( self.name + ": " + self.handle.before )
6007 main.cleanAndExit()
6008 except Exception:
6009 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006010 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006011
6012 def issu( self ):
6013 """
6014 Short summary of In-Service Software Upgrade status
6015
6016 Returns the output of the cli command or None on Error
6017 """
6018 try:
6019 cmdStr = "issu"
6020 handle = self.sendline( cmdStr )
6021 assert handle is not None, "Error in sendline"
6022 assert "Command not found:" not in handle, handle
6023 assert "Unsupported command:" not in handle, handle
6024 return handle
6025 except AssertionError:
6026 main.log.exception( "" )
6027 return None
6028 except TypeError:
6029 main.log.exception( self.name + ": Object not as expected" )
6030 return None
6031 except pexpect.EOF:
6032 main.log.error( self.name + ": EOF exception found" )
6033 main.log.error( self.name + ": " + self.handle.before )
6034 main.cleanAndExit()
6035 except Exception:
6036 main.log.exception( self.name + ": Uncaught exception!" )
6037 main.cleanAndExit()
6038
6039 def issuInit( self ):
6040 """
6041 Initiates an In-Service Software Upgrade
6042
6043 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6044 """
6045 try:
6046 cmdStr = "issu init"
6047 handle = self.sendline( cmdStr )
6048 assert handle is not None, "Error in sendline"
6049 assert "Command not found:" not in handle, handle
6050 assert "Unsupported command:" not in handle, handle
6051 if "Initialized" in handle:
6052 return main.TRUE
6053 else:
6054 return main.FALSE
6055 except AssertionError:
6056 main.log.exception( "" )
6057 return main.ERROR
6058 except TypeError:
6059 main.log.exception( self.name + ": Object not as expected" )
6060 return main.ERROR
6061 except pexpect.EOF:
6062 main.log.error( self.name + ": EOF exception found" )
6063 main.log.error( self.name + ": " + self.handle.before )
6064 main.cleanAndExit()
6065 except Exception:
6066 main.log.exception( self.name + ": Uncaught exception!" )
6067 main.cleanAndExit()
6068
6069 def issuUpgrade( self ):
6070 """
6071 Transitions stores to upgraded nodes
6072
6073 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6074 """
6075 try:
6076 cmdStr = "issu upgrade"
6077 handle = self.sendline( cmdStr )
6078 assert handle is not None, "Error in sendline"
6079 assert "Command not found:" not in handle, handle
6080 assert "Unsupported command:" not in handle, handle
6081 if "Upgraded" in handle:
6082 return main.TRUE
6083 else:
6084 return main.FALSE
6085 except AssertionError:
6086 main.log.exception( "" )
6087 return main.ERROR
6088 except TypeError:
6089 main.log.exception( self.name + ": Object not as expected" )
6090 return main.ERROR
6091 except pexpect.EOF:
6092 main.log.error( self.name + ": EOF exception found" )
6093 main.log.error( self.name + ": " + self.handle.before )
6094 main.cleanAndExit()
6095 except Exception:
6096 main.log.exception( self.name + ": Uncaught exception!" )
6097 main.cleanAndExit()
6098
6099 def issuCommit( self ):
6100 """
6101 Finalizes an In-Service Software Upgrade
6102
6103 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6104 """
6105 try:
6106 cmdStr = "issu commit"
6107 handle = self.sendline( cmdStr )
6108 assert handle is not None, "Error in sendline"
6109 assert "Command not found:" not in handle, handle
6110 assert "Unsupported command:" not in handle, handle
6111 # TODO: Check the version returned by this command
6112 if "Committed version" in handle:
6113 return main.TRUE
6114 else:
6115 return main.FALSE
6116 except AssertionError:
6117 main.log.exception( "" )
6118 return main.ERROR
6119 except TypeError:
6120 main.log.exception( self.name + ": Object not as expected" )
6121 return main.ERROR
6122 except pexpect.EOF:
6123 main.log.error( self.name + ": EOF exception found" )
6124 main.log.error( self.name + ": " + self.handle.before )
6125 main.cleanAndExit()
6126 except Exception:
6127 main.log.exception( self.name + ": Uncaught exception!" )
6128 main.cleanAndExit()
6129
6130 def issuRollback( self ):
6131 """
6132 Rolls back an In-Service Software Upgrade
6133
6134 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6135 """
6136 try:
6137 cmdStr = "issu rollback"
6138 handle = self.sendline( cmdStr )
6139 assert handle is not None, "Error in sendline"
6140 assert "Command not found:" not in handle, handle
6141 assert "Unsupported command:" not in handle, handle
6142 # TODO: Check the version returned by this command
6143 if "Rolled back to version" in handle:
6144 return main.TRUE
6145 else:
6146 return main.FALSE
6147 except AssertionError:
6148 main.log.exception( "" )
6149 return main.ERROR
6150 except TypeError:
6151 main.log.exception( self.name + ": Object not as expected" )
6152 return main.ERROR
6153 except pexpect.EOF:
6154 main.log.error( self.name + ": EOF exception found" )
6155 main.log.error( self.name + ": " + self.handle.before )
6156 main.cleanAndExit()
6157 except Exception:
6158 main.log.exception( self.name + ": Uncaught exception!" )
6159 main.cleanAndExit()
6160
6161 def issuReset( self ):
6162 """
6163 Resets the In-Service Software Upgrade status after a rollback
6164
6165 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6166 """
6167 try:
6168 cmdStr = "issu reset"
6169 handle = self.sendline( cmdStr )
6170 assert handle is not None, "Error in sendline"
6171 assert "Command not found:" not in handle, handle
6172 assert "Unsupported command:" not in handle, handle
6173 # TODO: Check the version returned by this command
6174 if "Reset version" in handle:
6175 return main.TRUE
6176 else:
6177 return main.FALSE
6178 except AssertionError:
6179 main.log.exception( "" )
6180 return main.ERROR
6181 except TypeError:
6182 main.log.exception( self.name + ": Object not as expected" )
6183 return main.ERROR
6184 except pexpect.EOF:
6185 main.log.error( self.name + ": EOF exception found" )
6186 main.log.error( self.name + ": " + self.handle.before )
6187 main.cleanAndExit()
6188 except Exception:
6189 main.log.exception( self.name + ": Uncaught exception!" )
6190 main.cleanAndExit()
6191
6192 def issuStatus( self ):
6193 """
6194 Status of an In-Service Software Upgrade
6195
6196 Returns the output of the cli command or None on Error
6197 """
6198 try:
6199 cmdStr = "issu status"
6200 handle = self.sendline( cmdStr )
6201 assert handle is not None, "Error in sendline"
6202 assert "Command not found:" not in handle, handle
6203 assert "Unsupported command:" not in handle, handle
6204 return handle
6205 except AssertionError:
6206 main.log.exception( "" )
6207 return None
6208 except TypeError:
6209 main.log.exception( self.name + ": Object not as expected" )
6210 return None
6211 except pexpect.EOF:
6212 main.log.error( self.name + ": EOF exception found" )
6213 main.log.error( self.name + ": " + self.handle.before )
6214 main.cleanAndExit()
6215 except Exception:
6216 main.log.exception( self.name + ": Uncaught exception!" )
6217 main.cleanAndExit()
6218
6219 def issuVersion( self ):
6220 """
6221 Get the version of an In-Service Software Upgrade
6222
6223 Returns the output of the cli command or None on Error
6224 """
6225 try:
6226 cmdStr = "issu version"
6227 handle = self.sendline( cmdStr )
6228 assert handle is not None, "Error in sendline"
6229 assert "Command not found:" not in handle, handle
6230 assert "Unsupported command:" not in handle, handle
6231 return handle
6232 except AssertionError:
6233 main.log.exception( "" )
6234 return None
6235 except TypeError:
6236 main.log.exception( self.name + ": Object not as expected" )
6237 return None
6238 except pexpect.EOF:
6239 main.log.error( self.name + ": EOF exception found" )
6240 main.log.error( self.name + ": " + self.handle.before )
6241 main.cleanAndExit()
6242 except Exception:
6243 main.log.exception( self.name + ": Uncaught exception!" )
6244 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006245
6246 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6247 """
6248 Create a multicast route by calling 'mcast-join' command
6249 sIP: source IP of the multicast route
6250 groupIP: group IP of the multicast route
6251 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6252 dPorts: a list of destination ports of the multicast route
6253 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6254 """
6255 try:
6256 cmdStr = "mcast-join"
6257 cmdStr += " " + str( sIP )
6258 cmdStr += " " + str( groupIP )
6259 cmdStr += " " + str( sPort )
6260 assert isinstance( dPorts, list )
6261 for dPort in dPorts:
6262 cmdStr += " " + str( dPort )
6263 handle = self.sendline( cmdStr )
6264 assert handle is not None, "Error in sendline"
6265 assert "Command not found:" not in handle, handle
6266 assert "Unsupported command:" not in handle, handle
6267 assert "Error executing command" not in handle, handle
6268 if "Added the mcast route" in handle:
6269 return main.TRUE
6270 else:
6271 return main.FALSE
6272 except AssertionError:
6273 main.log.exception( "" )
6274 return None
6275 except TypeError:
6276 main.log.exception( self.name + ": Object not as expected" )
6277 return None
6278 except pexpect.EOF:
6279 main.log.error( self.name + ": EOF exception found" )
6280 main.log.error( self.name + ": " + self.handle.before )
6281 main.cleanAndExit()
6282 except Exception:
6283 main.log.exception( self.name + ": Uncaught exception!" )
6284 main.cleanAndExit()
6285
6286 def mcastDelete( self, sIP, groupIP, dPorts ):
6287 """
6288 Delete a multicast route by calling 'mcast-delete' command
6289 sIP: source IP of the multicast route
6290 groupIP: group IP of the multicast route
6291 dPorts: a list of destination ports of the multicast route
6292 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6293 """
6294 try:
6295 cmdStr = "mcast-delete"
6296 cmdStr += " " + str( sIP )
6297 cmdStr += " " + str( groupIP )
6298 assert isinstance( dPorts, list )
6299 for dPort in dPorts:
6300 cmdStr += " " + str( dPort )
6301 handle = self.sendline( cmdStr )
6302 assert handle is not None, "Error in sendline"
6303 assert "Command not found:" not in handle, handle
6304 assert "Unsupported command:" not in handle, handle
6305 assert "Error executing command" not in handle, handle
6306 if "Updated the mcast route" in handle:
6307 return main.TRUE
6308 else:
6309 return main.FALSE
6310 except AssertionError:
6311 main.log.exception( "" )
6312 return None
6313 except TypeError:
6314 main.log.exception( self.name + ": Object not as expected" )
6315 return None
6316 except pexpect.EOF:
6317 main.log.error( self.name + ": EOF exception found" )
6318 main.log.error( self.name + ": " + self.handle.before )
6319 main.cleanAndExit()
6320 except Exception:
6321 main.log.exception( self.name + ": Uncaught exception!" )
6322 main.cleanAndExit()
6323
6324 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6325 """
6326 Create a multicast route by calling 'mcast-host-join' command
6327 sAddr: we can provide * for ASM or a specific address for SSM
6328 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006329 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006330 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6331 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6332 """
6333 try:
6334 cmdStr = "mcast-host-join"
6335 cmdStr += " -sAddr " + str( sAddr )
6336 cmdStr += " -gAddr " + str( gAddr )
6337 assert isinstance( srcs, list )
6338 for src in srcs:
6339 cmdStr += " -srcs " + str( src )
6340 assert isinstance( sinks, list )
6341 for sink in sinks:
6342 cmdStr += " -sinks " + str( sink )
6343 handle = self.sendline( cmdStr )
6344 assert handle is not None, "Error in sendline"
6345 assert "Command not found:" not in handle, handle
6346 assert "Unsupported command:" not in handle, handle
6347 assert "Error executing command" not in handle, handle
6348 if "Added the mcast route" in handle:
6349 return main.TRUE
6350 else:
6351 return main.FALSE
6352 except AssertionError:
6353 main.log.exception( "" )
6354 return None
6355 except TypeError:
6356 main.log.exception( self.name + ": Object not as expected" )
6357 return None
6358 except pexpect.EOF:
6359 main.log.error( self.name + ": EOF exception found" )
6360 main.log.error( self.name + ": " + self.handle.before )
6361 main.cleanAndExit()
6362 except Exception:
6363 main.log.exception( self.name + ": Uncaught exception!" )
6364 main.cleanAndExit()
6365
6366 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6367 """
6368 Delete multicast sink(s) by calling 'mcast-host-delete' command
6369 sAddr: we can provide * for ASM or a specific address for SSM
6370 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006371 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006372 will delete the route if not specified
6373 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6374 """
6375 try:
6376 cmdStr = "mcast-host-delete"
6377 cmdStr += " -sAddr " + str( sAddr )
6378 cmdStr += " -gAddr " + str( gAddr )
6379 if host:
6380 cmdStr += " -h " + str( host )
6381 handle = self.sendline( cmdStr )
6382 assert handle is not None, "Error in sendline"
6383 assert "Command not found:" not in handle, handle
6384 assert "Unsupported command:" not in handle, handle
6385 assert "Error executing command" not in handle, handle
6386 if "Updated the mcast route" in handle:
6387 return main.TRUE
6388 elif "Deleted the mcast route" in handle:
6389 return main.TRUE
6390 else:
6391 return main.FALSE
6392 except AssertionError:
6393 main.log.exception( "" )
6394 return None
6395 except TypeError:
6396 main.log.exception( self.name + ": Object not as expected" )
6397 return None
6398 except pexpect.EOF:
6399 main.log.error( self.name + ": EOF exception found" )
6400 main.log.error( self.name + ": " + self.handle.before )
6401 main.cleanAndExit()
6402 except Exception:
6403 main.log.exception( self.name + ": Uncaught exception!" )
6404 main.cleanAndExit()
6405
You Wang547893e2018-05-08 13:34:59 -07006406 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6407 """
6408 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6409 sAddr: we can provide * for ASM or a specific address for SSM
6410 gAddr: specifies multicast group address
6411 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6412 will delete the route if not specified
6413 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6414 """
6415 try:
6416 cmdStr = "mcast-sink-delete"
6417 cmdStr += " -sAddr " + str( sAddr )
6418 cmdStr += " -gAddr " + str( gAddr )
6419 if sink:
6420 cmdStr += " -s " + str( sink )
6421 handle = self.sendline( cmdStr )
6422 assert handle is not None, "Error in sendline"
6423 assert "Command not found:" not in handle, handle
6424 assert "Unsupported command:" not in handle, handle
6425 assert "Error executing command" not in handle, handle
6426 if "Updated the mcast route" in handle:
6427 return main.TRUE
6428 elif "Deleted the mcast route" in handle:
6429 return main.TRUE
6430 else:
6431 return main.FALSE
6432 except AssertionError:
6433 main.log.exception( "" )
6434 return None
6435 except TypeError:
6436 main.log.exception( self.name + ": Object not as expected" )
6437 return None
6438 except pexpect.EOF:
6439 main.log.error( self.name + ": EOF exception found" )
6440 main.log.error( self.name + ": " + self.handle.before )
6441 main.cleanAndExit()
6442 except Exception:
6443 main.log.exception( self.name + ": Uncaught exception!" )
6444 main.cleanAndExit()
6445
You Wange24d6272018-03-27 21:18:50 -07006446 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6447 """
6448 Delete multicast src(s) by calling 'mcast-source-delete' command
6449 sAddr: we can provide * for ASM or a specific address for SSM
6450 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006451 srcs: a list of host IDs of the sources e.g. ["00:AA:00:00:01:05/40"],
You Wange24d6272018-03-27 21:18:50 -07006452 will delete the route if not specified
6453 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6454 """
6455 try:
6456 cmdStr = "mcast-source-delete"
6457 cmdStr += " -sAddr " + str( sAddr )
6458 cmdStr += " -gAddr " + str( gAddr )
6459 if srcs:
6460 assert isinstance( srcs, list )
6461 for src in srcs:
6462 cmdStr += " -src " + str( src )
6463 handle = self.sendline( cmdStr )
6464 assert handle is not None, "Error in sendline"
6465 assert "Command not found:" not in handle, handle
6466 assert "Unsupported command:" not in handle, handle
6467 assert "Error executing command" not in handle, handle
6468 if "Updated the mcast route" in handle:
6469 return main.TRUE
6470 elif "Deleted the mcast route" in handle:
6471 return main.TRUE
6472 else:
6473 return main.FALSE
6474 except AssertionError:
6475 main.log.exception( "" )
6476 return None
6477 except TypeError:
6478 main.log.exception( self.name + ": Object not as expected" )
6479 return None
6480 except pexpect.EOF:
6481 main.log.error( self.name + ": EOF exception found" )
6482 main.log.error( self.name + ": " + self.handle.before )
6483 main.cleanAndExit()
6484 except Exception:
6485 main.log.exception( self.name + ": Uncaught exception!" )
6486 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006487
6488 def netcfg( self, jsonFormat=True, args="" ):
6489 """
6490 Run netcfg cli command with given args
6491 """
6492 try:
6493 cmdStr = "netcfg"
6494 if jsonFormat:
6495 cmdStr = cmdStr + " -j"
6496 if args:
6497 cmdStr = cmdStr + " " + str( args )
6498 handle = self.sendline( cmdStr )
6499 assert handle is not None, "Error in sendline"
6500 assert "Command not found:" not in handle, handle
6501 assert "Unsupported command:" not in handle, handle
6502 assert "Error executing command" not in handle, handle
6503 return handle
6504 except AssertionError:
6505 main.log.exception( "" )
6506 return None
6507 except TypeError:
6508 main.log.exception( self.name + ": Object not as expected" )
6509 return None
6510 except pexpect.EOF:
6511 main.log.error( self.name + ": EOF exception found" )
6512 main.log.error( self.name + ": " + self.handle.before )
6513 main.cleanAndExit()
6514 except Exception:
6515 main.log.exception( self.name + ": Uncaught exception!" )
6516 main.cleanAndExit()
6517
You Wang0fa76e72018-05-18 11:33:25 -07006518 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006519 """
You Wang54b1d672018-06-11 16:44:13 -07006520 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006521 Options:
6522 sAddr: IP address of the source host
6523 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006524 ipv6: True if hosts are IPv6
6525 verbose: return verbose t3 output if True
6526 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006527 """
6528 try:
6529 # Collect information of both hosts from onos
6530 hosts = self.hosts()
6531 hosts = json.loads( hosts )
6532 sHost = None
6533 dHost = None
6534 for host in hosts:
6535 if sAddr in host[ "ipAddresses" ]:
6536 sHost = host
6537 elif dAddr in host[ "ipAddresses" ]:
6538 dHost = host
6539 if sHost and dHost:
6540 break
6541 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006542 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006543 if simple:
6544 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006545 cmdStr = "t3-troubleshoot-simple"
6546 if verbose:
6547 cmdStr += " -vv"
6548 if ipv6:
6549 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006550 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006551 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006552 else:
You Wang54b1d672018-06-11 16:44:13 -07006553 for location in sHost[ "locations" ]:
6554 cmdStr = "t3-troubleshoot"
6555 if verbose:
6556 cmdStr += " -vv"
6557 if ipv6:
6558 cmdStr += " -et ipv6"
6559 cmdStr += " -s " + str( sAddr )
6560 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6561 cmdStr += " -sm " + str( sHost[ "mac" ] )
6562 if sHost[ "vlan" ] != "None":
6563 cmdStr += " -vid " + sHost[ "vlan" ]
6564 cmdStr += " -d " + str( dAddr )
6565 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6566 netcfg = json.loads( netcfg )
6567 assert netcfg, "Failed to get netcfg"
6568 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6569 cmdList.append( cmdStr )
6570 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006571 except AssertionError:
6572 main.log.exception( "" )
6573 return None
6574 except ( KeyError, TypeError ):
6575 main.log.exception( self.name + ": Object not as expected" )
6576 return None
6577 except Exception:
6578 main.log.exception( self.name + ": Uncaught exception!" )
6579 main.cleanAndExit()
6580
6581 def t3( self, sAddr, dAddr, ipv6=False ):
6582 """
You Wang54b1d672018-06-11 16:44:13 -07006583 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006584 Options:
6585 sAddr: IP address of the source host
6586 dAddr: IP address of the destination host
6587 """
6588 try:
You Wang54b1d672018-06-11 16:44:13 -07006589 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6590 assert cmdList is not None, "composeT3Command returned None"
6591 t3Output = ""
6592 for cmdStr in cmdList:
6593 handle = self.sendline( cmdStr )
6594 assert handle is not None, "Error in sendline"
6595 assert "Command not found:" not in handle, handle
6596 assert "Unsupported command:" not in handle, handle
6597 assert "Error executing command" not in handle, handle
6598 assert "Tracing packet" in handle
6599 t3Output += handle
6600 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006601 except AssertionError:
6602 main.log.exception( "" )
6603 return None
6604 except pexpect.EOF:
6605 main.log.error( self.name + ": EOF exception found" )
6606 main.log.error( self.name + ": " + self.handle.before )
6607 main.cleanAndExit()
6608 except Exception:
6609 main.log.exception( self.name + ": Uncaught exception!" )
6610 main.cleanAndExit()