blob: 54db7e4280f0af87bac25a18e76212b589fc0651 [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 Wang141b43b2018-06-26 16:50:18 -0700592 self.handle.send( "\x03" )
593 self.handle.expect( "onos>" )
GlennRCed771242016-01-13 17:02:47 -0800594 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700595 except IndexError:
596 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700597 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700598 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800599 except TypeError:
600 main.log.exception( self.name + ": Object not as expected" )
601 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400602 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800603 main.log.error( self.name + ": EOF exception found" )
604 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700605 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700606 return None
607 else:
Devin Lim44075962017-08-11 10:56:37 -0700608 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800609 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800610 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700611 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700612 return None
613 else:
Devin Lim44075962017-08-11 10:56:37 -0700614 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400615
kelvin8ec71442015-01-15 16:57:00 -0800616 # IMPORTANT NOTE:
617 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800618 # the cli command changing 'a:b' with 'aB'.
619 # Ex ) onos:topology > onosTopology
620 # onos:links > onosLinks
621 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800622
kelvin-onlabd3b64892015-01-20 13:26:24 -0800623 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800624 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400625 Adds a new cluster node by ID and address information.
626 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 * nodeId
628 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400629 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800630 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800631 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400632 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800633 cmdStr = "add-node " + str( nodeId ) + " " +\
634 str( ONOSIp ) + " " + str( tcpPort )
635 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700636 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800637 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800638 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700639 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800640 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800641 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400642 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800643 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400644 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800645 except AssertionError:
646 main.log.exception( "" )
647 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800648 except TypeError:
649 main.log.exception( self.name + ": Object not as expected" )
650 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400651 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800652 main.log.error( self.name + ": EOF exception found" )
653 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700654 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800655 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800656 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700657 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400658
kelvin-onlabd3b64892015-01-20 13:26:24 -0800659 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800660 """
andrewonlab86dc3082014-10-13 18:18:38 -0400661 Removes a cluster by ID
662 Issues command: 'remove-node [<node-id>]'
663 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800664 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800665 """
andrewonlab86dc3082014-10-13 18:18:38 -0400666 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400667
kelvin-onlabd3b64892015-01-20 13:26:24 -0800668 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700669 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700670 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800671 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700672 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700673 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700674 main.log.error( handle )
675 return main.FALSE
676 else:
677 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800678 except AssertionError:
679 main.log.exception( "" )
680 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800681 except TypeError:
682 main.log.exception( self.name + ": Object not as expected" )
683 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400684 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800685 main.log.error( self.name + ": EOF exception found" )
686 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700687 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800688 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800689 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700690 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400691
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700692 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800693 """
andrewonlab7c211572014-10-15 16:45:20 -0400694 List the nodes currently visible
695 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700696 Optional argument:
697 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800698 """
andrewonlab7c211572014-10-15 16:45:20 -0400699 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700700 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700701 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700702 cmdStr += " -j"
703 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700704 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800705 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700706 return output
Jon Hallc6793552016-01-19 14:18:37 -0800707 except AssertionError:
708 main.log.exception( "" )
709 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800710 except TypeError:
711 main.log.exception( self.name + ": Object not as expected" )
712 return None
andrewonlab7c211572014-10-15 16:45:20 -0400713 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800714 main.log.error( self.name + ": EOF exception found" )
715 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700716 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800717 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800718 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700719 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400720
kelvin8ec71442015-01-15 16:57:00 -0800721 def topology( self ):
722 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700723 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700724 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700725 Return:
726 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800727 """
andrewonlab95ce8322014-10-13 14:12:04 -0400728 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700729 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800730 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800731 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800732 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700733 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400734 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800735 except AssertionError:
736 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800737 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800738 except TypeError:
739 main.log.exception( self.name + ": Object not as expected" )
740 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400741 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800742 main.log.error( self.name + ": EOF exception found" )
743 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700744 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800745 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800746 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700747 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800748
jenkins7ead5a82015-03-13 10:28:21 -0700749 def deviceRemove( self, deviceId ):
750 """
751 Removes particular device from storage
752
753 TODO: refactor this function
754 """
755 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700756 cmdStr = "device-remove " + str( deviceId )
757 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800758 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800759 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700760 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700761 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700762 main.log.error( handle )
763 return main.FALSE
764 else:
765 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800766 except AssertionError:
767 main.log.exception( "" )
768 return None
jenkins7ead5a82015-03-13 10:28:21 -0700769 except TypeError:
770 main.log.exception( self.name + ": Object not as expected" )
771 return None
772 except pexpect.EOF:
773 main.log.error( self.name + ": EOF exception found" )
774 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700775 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700776 except Exception:
777 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700778 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700779
You Wang3b9689a2018-08-30 12:24:00 -0700780 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800781 """
Jon Hall7b02d952014-10-17 20:14:54 -0400782 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400783 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800784 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800785 """
andrewonlab86dc3082014-10-13 18:18:38 -0400786 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700787 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800788 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700789 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700790 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800791 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800792 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700793 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800794 except AssertionError:
795 main.log.exception( "" )
796 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800797 except TypeError:
798 main.log.exception( self.name + ": Object not as expected" )
799 return None
andrewonlab7c211572014-10-15 16:45:20 -0400800 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800801 main.log.error( self.name + ": EOF exception found" )
802 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700803 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800804 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800805 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700806 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400807
kelvin-onlabd3b64892015-01-20 13:26:24 -0800808 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800809 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800810 This balances the devices across all controllers
811 by issuing command: 'onos> onos:balance-masters'
812 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800813 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800814 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800815 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700816 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800817 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800818 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700819 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700820 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700821 main.log.error( handle )
822 return main.FALSE
823 else:
824 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800825 except AssertionError:
826 main.log.exception( "" )
827 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800828 except TypeError:
829 main.log.exception( self.name + ": Object not as expected" )
830 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800831 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800832 main.log.error( self.name + ": EOF exception found" )
833 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700834 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800835 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800836 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700837 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800838
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000839 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700840 """
841 Returns the output of the masters command.
842 Optional argument:
843 * jsonFormat - boolean indicating if you want output in json
844 """
845 try:
846 cmdStr = "onos:masters"
847 if jsonFormat:
848 cmdStr += " -j"
849 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700850 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800851 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700852 return output
Jon Hallc6793552016-01-19 14:18:37 -0800853 except AssertionError:
854 main.log.exception( "" )
855 return None
acsmars24950022015-07-30 18:00:43 -0700856 except TypeError:
857 main.log.exception( self.name + ": Object not as expected" )
858 return None
859 except pexpect.EOF:
860 main.log.error( self.name + ": EOF exception found" )
861 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700862 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700863 except Exception:
864 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700865 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700866
Jon Hallc6793552016-01-19 14:18:37 -0800867 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700868 """
869 Uses the master command to check that the devices' leadership
870 is evenly divided
871
872 Dependencies: checkMasters() and summary()
873
Jon Hall6509dbf2016-06-21 17:01:17 -0700874 Returns main.TRUE if the devices are balanced
875 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700876 Exits on Exception
877 Returns None on TypeError
878 """
879 try:
Jon Hallc6793552016-01-19 14:18:37 -0800880 summaryOutput = self.summary()
881 totalDevices = json.loads( summaryOutput )[ "devices" ]
882 except ( TypeError, ValueError ):
883 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
884 return None
885 try:
acsmars24950022015-07-30 18:00:43 -0700886 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800887 mastersOutput = self.checkMasters()
888 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700889 first = masters[ 0 ][ "size" ]
890 for master in masters:
891 totalOwnedDevices += master[ "size" ]
892 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
893 main.log.error( "Mastership not balanced" )
894 main.log.info( "\n" + self.checkMasters( False ) )
895 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700896 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700897 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700898 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800899 except ( TypeError, ValueError ):
900 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700901 return None
902 except pexpect.EOF:
903 main.log.error( self.name + ": EOF exception found" )
904 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700905 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700906 except Exception:
907 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700908 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700909
YPZhangfebf7302016-05-24 16:45:56 -0700910 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800911 """
Jon Halle8217482014-10-17 13:49:14 -0400912 Lists all core links
913 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800914 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800915 """
Jon Halle8217482014-10-17 13:49:14 -0400916 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700917 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800918 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700919 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700920 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800921 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800922 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700923 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800924 except AssertionError:
925 main.log.exception( "" )
926 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800927 except TypeError:
928 main.log.exception( self.name + ": Object not as expected" )
929 return None
Jon Halle8217482014-10-17 13:49:14 -0400930 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800931 main.log.error( self.name + ": EOF exception found" )
932 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700933 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800934 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800935 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700936 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400937
You Wang3b9689a2018-08-30 12:24:00 -0700938 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800939 """
Jon Halle8217482014-10-17 13:49:14 -0400940 Lists all ports
941 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800942 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800943 """
Jon Halle8217482014-10-17 13:49:14 -0400944 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700945 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800946 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700947 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700948 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800949 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800950 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700951 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800952 except AssertionError:
953 main.log.exception( "" )
954 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800955 except TypeError:
956 main.log.exception( self.name + ": Object not as expected" )
957 return None
Jon Halle8217482014-10-17 13:49:14 -0400958 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800959 main.log.error( self.name + ": EOF exception found" )
960 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700961 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800962 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800963 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700964 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400965
kelvin-onlabd3b64892015-01-20 13:26:24 -0800966 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800967 """
Jon Hall983a1702014-10-28 18:44:22 -0400968 Lists all devices and the controllers with roles assigned to them
969 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800970 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800971 """
andrewonlab7c211572014-10-15 16:45:20 -0400972 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700973 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800974 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700975 cmdStr += " -j"
976 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800977 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800978 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700979 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800980 except AssertionError:
981 main.log.exception( "" )
982 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800983 except TypeError:
984 main.log.exception( self.name + ": Object not as expected" )
985 return None
Jon Hall983a1702014-10-28 18:44:22 -0400986 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800987 main.log.error( self.name + ": EOF exception found" )
988 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700989 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800990 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800991 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700992 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -0400993
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800995 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800996 Given the a string containing the json representation of the "roles"
997 cli command and a partial or whole device id, returns a json object
998 containing the roles output for the first device whose id contains
999 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001000
1001 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001002 A dict of the role assignments for the given device or
1003 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001004 """
Jon Hall983a1702014-10-28 18:44:22 -04001005 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001006 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001007 return None
1008 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001009 rawRoles = self.roles()
1010 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001011 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001012 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001013 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001015 return device
1016 return None
Jon Hallc6793552016-01-19 14:18:37 -08001017 except ( TypeError, ValueError ):
1018 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001019 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001020 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001021 main.log.error( self.name + ": EOF exception found" )
1022 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001023 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001024 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001025 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001026 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001027
kelvin-onlabd3b64892015-01-20 13:26:24 -08001028 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001029 """
Jon Hall94fd0472014-12-08 11:52:42 -08001030 Iterates through each device and checks if there is a master assigned
1031 Returns: main.TRUE if each device has a master
1032 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001033 """
Jon Hall94fd0472014-12-08 11:52:42 -08001034 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001035 rawRoles = self.roles()
1036 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001037 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001038 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001039 # print device
1040 if device[ 'master' ] == "none":
1041 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001042 return main.FALSE
1043 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001044 except ( TypeError, ValueError ):
1045 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001046 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001047 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001048 main.log.error( self.name + ": EOF exception found" )
1049 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001050 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001051 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001052 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001053 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001054
kelvin-onlabd3b64892015-01-20 13:26:24 -08001055 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001056 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001057 Returns string of paths, and the cost.
1058 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001059 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001060 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001061 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1062 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001063 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001064 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001065 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001066 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001067 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001068 else:
kelvin8ec71442015-01-15 16:57:00 -08001069 path = handle.split( ";" )[ 0 ]
1070 cost = handle.split( ";" )[ 1 ]
1071 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001072 except AssertionError:
1073 main.log.exception( "" )
1074 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001075 except TypeError:
1076 main.log.exception( self.name + ": Object not as expected" )
1077 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001078 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001079 main.log.error( self.name + ": EOF exception found" )
1080 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001081 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001082 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001083 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001084 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001085
kelvin-onlabd3b64892015-01-20 13:26:24 -08001086 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001087 """
Jon Hallffb386d2014-11-21 13:43:38 -08001088 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001089 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001090 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001091 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001092 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001093 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001094 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001095 cmdStr += " -j"
1096 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001097 if handle:
1098 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001099 # TODO: Maybe make this less hardcoded
1100 # ConsistentMap Exceptions
1101 assert "org.onosproject.store.service" not in handle
1102 # Node not leader
1103 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001104 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001105 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001106 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001107 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001108 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001109 except TypeError:
1110 main.log.exception( self.name + ": Object not as expected" )
1111 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001112 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001113 main.log.error( self.name + ": EOF exception found" )
1114 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001115 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001116 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001117 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001118 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001119
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001121 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001122 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001123
Jon Hallefbd9792015-03-05 16:11:36 -08001124 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001125 partial mac address
1126
Jon Hall42db6dc2014-10-24 19:03:48 -04001127 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001128 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001129 try:
kelvin8ec71442015-01-15 16:57:00 -08001130 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001131 return None
1132 else:
1133 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 rawHosts = self.hosts()
1135 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001136 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001137 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001138 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001139 if not host:
1140 pass
1141 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001142 return host
1143 return None
Jon Hallc6793552016-01-19 14:18:37 -08001144 except ( TypeError, ValueError ):
1145 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001146 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001147 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001148 main.log.error( self.name + ": EOF exception found" )
1149 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001150 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001151 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001152 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001153 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001154
kelvin-onlabd3b64892015-01-20 13:26:24 -08001155 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001156 """
1157 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001158 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001159
andrewonlab3f0a4af2014-10-17 12:25:14 -04001160 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001161 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001162 IMPORTANT:
1163 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001164 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001165 Furthermore, it assumes that value of VLAN is '-1'
1166 Description:
kelvin8ec71442015-01-15 16:57:00 -08001167 Converts mininet hosts ( h1, h2, h3... ) into
1168 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1169 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001170 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001171 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001172
kelvin-onlabd3b64892015-01-20 13:26:24 -08001173 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001174 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001175 hostHex = hex( int( host ) ).zfill( 12 )
1176 hostHex = str( hostHex ).replace( 'x', '0' )
1177 i = iter( str( hostHex ) )
1178 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1179 hostHex = hostHex + "/-1"
1180 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001181
kelvin-onlabd3b64892015-01-20 13:26:24 -08001182 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001183
Jon Halld4d4b372015-01-28 16:02:41 -08001184 except TypeError:
1185 main.log.exception( self.name + ": Object not as expected" )
1186 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001187 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001188 main.log.error( self.name + ": EOF exception found" )
1189 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001190 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001191 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001192 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001193 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001194
You Wangbc898b82018-05-03 16:22:34 -07001195 def verifyHostLocation( self, hostIp, location ):
1196 """
1197 Description:
1198 Verify the host given is discovered in all locations expected
1199 Required:
1200 hostIp: IP address of the host
1201 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1202 Could be a string or list
1203 Returns:
1204 main.TRUE if host is discovered on all locations provided
1205 main.FALSE otherwise
1206 """
1207 import json
1208 locations = [ location ] if isinstance( location, str ) else location
1209 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1210 try:
1211 hosts = self.hosts()
1212 hosts = json.loads( hosts )
1213 targetHost = None
1214 for host in hosts:
1215 if hostIp in host[ "ipAddresses" ]:
1216 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001217 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001218 result = main.TRUE
1219 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1220 for loc in locations:
1221 discovered = False
1222 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001223 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1224 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001225 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001226 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001227 break
1228 if discovered:
1229 locationsDiscovered.remove( locDiscovered )
1230 else:
1231 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1232 result = main.FALSE
1233 if locationsDiscovered:
1234 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1235 result = main.FALSE
1236 return result
1237 except KeyError:
1238 main.log.exception( self.name + ": host data not as expected: " + hosts )
1239 return None
1240 except pexpect.EOF:
1241 main.log.error( self.name + ": EOF exception found" )
1242 main.log.error( self.name + ": " + self.handle.before )
1243 main.cleanAndExit()
1244 except Exception:
1245 main.log.exception( self.name + ": Uncaught exception" )
1246 return None
1247
You Wang53dba1e2018-02-02 17:45:44 -08001248 def verifyHostIp( self, hostList=[], prefix="" ):
1249 """
1250 Description:
1251 Verify that all hosts have IP address assigned to them
1252 Optional:
1253 hostList: If specified, verifications only happen to the hosts
1254 in hostList
1255 prefix: at least one of the ip address assigned to the host
1256 needs to have the specified prefix
1257 Returns:
1258 main.TRUE if all hosts have specific IP address assigned;
1259 main.FALSE otherwise
1260 """
1261 import json
1262 try:
1263 hosts = self.hosts()
1264 hosts = json.loads( hosts )
1265 if not hostList:
1266 hostList = [ host[ "id" ] for host in hosts ]
1267 for host in hosts:
1268 hostId = host[ "id" ]
1269 if hostId not in hostList:
1270 continue
1271 ipList = host[ "ipAddresses" ]
1272 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1273 if not ipList:
1274 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1275 else:
1276 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1277 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1278 else:
1279 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1280 hostList.remove( hostId )
1281 if hostList:
1282 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1283 return main.FALSE
1284 else:
1285 return main.TRUE
1286 except KeyError:
1287 main.log.exception( self.name + ": host data not as expected: " + hosts )
1288 return None
1289 except pexpect.EOF:
1290 main.log.error( self.name + ": EOF exception found" )
1291 main.log.error( self.name + ": " + self.handle.before )
1292 main.cleanAndExit()
1293 except Exception:
1294 main.log.exception( self.name + ": Uncaught exception" )
1295 return None
1296
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001297 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001298 """
andrewonlabe6745342014-10-17 14:29:13 -04001299 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001300 * hostIdOne: ONOS host id for host1
1301 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001302 Optional:
1303 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001304 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001305 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001306 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001307 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001308 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001309 Returns:
1310 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001311 """
andrewonlabe6745342014-10-17 14:29:13 -04001312 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001313 cmdStr = "add-host-intent "
1314 if vlanId:
1315 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001316 if setVlan:
1317 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001318 if encap:
1319 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001320 if bandwidth:
1321 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001322 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001323 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001324 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001325 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001326 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001327 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001328 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001329 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001330 else:
1331 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001332 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001333 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001334 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001335 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001336 else:
1337 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001338 main.log.debug( "Response from ONOS was: " +
1339 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001340 return None
Jon Hallc6793552016-01-19 14:18:37 -08001341 except AssertionError:
1342 main.log.exception( "" )
1343 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001344 except TypeError:
1345 main.log.exception( self.name + ": Object not as expected" )
1346 return None
andrewonlabe6745342014-10-17 14:29:13 -04001347 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001348 main.log.error( self.name + ": EOF exception found" )
1349 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001350 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001351 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001352 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001353 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001354
kelvin-onlabd3b64892015-01-20 13:26:24 -08001355 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001356 """
andrewonlab7b31d232014-10-24 13:31:47 -04001357 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001358 * ingressDevice: device id of ingress device
1359 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001360 Optional:
1361 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001362 Description:
1363 Adds an optical intent by specifying an ingress and egress device
1364 Returns:
1365 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001366 """
andrewonlab7b31d232014-10-24 13:31:47 -04001367 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001368 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1369 " " + str( egressDevice )
1370 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001371 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001372 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001373 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001374 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001375 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001376 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001377 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001378 main.log.info( "Optical intent installed between " +
1379 str( ingressDevice ) + " and " +
1380 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001381 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001382 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001383 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001384 else:
1385 main.log.error( "Error, intent ID not found" )
1386 return None
Jon Hallc6793552016-01-19 14:18:37 -08001387 except AssertionError:
1388 main.log.exception( "" )
1389 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001390 except TypeError:
1391 main.log.exception( self.name + ": Object not as expected" )
1392 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001393 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001394 main.log.error( self.name + ": EOF exception found" )
1395 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001396 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001397 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001398 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001399 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001400
kelvin-onlabd3b64892015-01-20 13:26:24 -08001401 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001402 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001403 ingressDevice,
1404 egressDevice,
1405 portIngress="",
1406 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001407 ethType="",
1408 ethSrc="",
1409 ethDst="",
1410 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001411 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001412 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001413 ipProto="",
1414 ipSrc="",
1415 ipDst="",
1416 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001417 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001418 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001419 setVlan="",
1420 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001421 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001422 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001423 * ingressDevice: device id of ingress device
1424 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001425 Optional:
1426 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001427 * ethSrc: specify ethSrc ( i.e. src mac addr )
1428 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001429 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001430 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001431 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001432 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001433 * ipSrc: specify ip source address
1434 * ipDst: specify ip destination address
1435 * tcpSrc: specify tcp source port
1436 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001437 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001438 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001439 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001440 Description:
kelvin8ec71442015-01-15 16:57:00 -08001441 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001442 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001443 Returns:
1444 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001445
Jon Halle3f39ff2015-01-13 11:50:53 -08001446 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001447 options developers provide for point-to-point
1448 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001449 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001450 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001451 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001452
Jeremy Songsterff553672016-05-12 17:06:23 -07001453 if ethType:
1454 cmd += " --ethType " + str( ethType )
1455 if ethSrc:
1456 cmd += " --ethSrc " + str( ethSrc )
1457 if ethDst:
1458 cmd += " --ethDst " + str( ethDst )
1459 if bandwidth:
1460 cmd += " --bandwidth " + str( bandwidth )
1461 if lambdaAlloc:
1462 cmd += " --lambda "
1463 if ipProto:
1464 cmd += " --ipProto " + str( ipProto )
1465 if ipSrc:
1466 cmd += " --ipSrc " + str( ipSrc )
1467 if ipDst:
1468 cmd += " --ipDst " + str( ipDst )
1469 if tcpSrc:
1470 cmd += " --tcpSrc " + str( tcpSrc )
1471 if tcpDst:
1472 cmd += " --tcpDst " + str( tcpDst )
1473 if vlanId:
1474 cmd += " -v " + str( vlanId )
1475 if setVlan:
1476 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001477 if encap:
1478 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001479 if protected:
1480 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001481
kelvin8ec71442015-01-15 16:57:00 -08001482 # Check whether the user appended the port
1483 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001484 if "/" in ingressDevice:
1485 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001486 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001487 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001488 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001489 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001490 # Would it make sense to throw an exception and exit
1491 # the test?
1492 return None
andrewonlab36af3822014-11-18 17:48:18 -05001493
kelvin8ec71442015-01-15 16:57:00 -08001494 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001495 str( ingressDevice ) + "/" +\
1496 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001497
kelvin-onlabd3b64892015-01-20 13:26:24 -08001498 if "/" in egressDevice:
1499 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001500 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001501 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001502 main.log.error( "You must specify the egress port" )
1503 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001504
kelvin8ec71442015-01-15 16:57:00 -08001505 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001506 str( egressDevice ) + "/" +\
1507 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001508
kelvin-onlab898a6c62015-01-16 14:13:53 -08001509 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001510 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001511 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001512 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001513 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001514 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001515 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001516 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001517 # TODO: print out all the options in this message?
1518 main.log.info( "Point-to-point intent installed between " +
1519 str( ingressDevice ) + " and " +
1520 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001521 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001522 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001523 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001524 else:
1525 main.log.error( "Error, intent ID not found" )
1526 return None
Jon Hallc6793552016-01-19 14:18:37 -08001527 except AssertionError:
1528 main.log.exception( "" )
1529 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001530 except TypeError:
1531 main.log.exception( self.name + ": Object not as expected" )
1532 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001533 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001534 main.log.error( self.name + ": EOF exception found" )
1535 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001536 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001537 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001538 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001539 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001540
kelvin-onlabd3b64892015-01-20 13:26:24 -08001541 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001542 self,
shahshreyac2f97072015-03-19 17:04:29 -07001543 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001544 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001545 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001546 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001547 ethType="",
1548 ethSrc="",
1549 ethDst="",
1550 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001551 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001552 ipProto="",
1553 ipSrc="",
1554 ipDst="",
1555 tcpSrc="",
1556 tcpDst="",
1557 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001558 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001559 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001560 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001561 partial=False,
1562 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001563 """
shahshreyad0c80432014-12-04 16:56:05 -08001564 Note:
shahshreya70622b12015-03-19 17:19:00 -07001565 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001566 is same. That is, all ingress devices include port numbers
1567 with a "/" or all ingress devices could specify device
1568 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001569 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001570 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001571 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001572 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001573 Optional:
1574 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001575 * ethSrc: specify ethSrc ( i.e. src mac addr )
1576 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001577 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001578 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001579 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001580 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001581 * ipSrc: specify ip source address
1582 * ipDst: specify ip destination address
1583 * tcpSrc: specify tcp source port
1584 * tcpDst: specify tcp destination port
1585 * setEthSrc: action to Rewrite Source MAC Address
1586 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001587 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001588 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001589 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001590 Description:
kelvin8ec71442015-01-15 16:57:00 -08001591 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001592 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001593 Returns:
1594 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001595
Jon Halle3f39ff2015-01-13 11:50:53 -08001596 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001597 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001598 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001599 """
shahshreyad0c80432014-12-04 16:56:05 -08001600 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001601 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001602
Jeremy Songsterff553672016-05-12 17:06:23 -07001603 if ethType:
1604 cmd += " --ethType " + str( ethType )
1605 if ethSrc:
1606 cmd += " --ethSrc " + str( ethSrc )
1607 if ethDst:
1608 cmd += " --ethDst " + str( ethDst )
1609 if bandwidth:
1610 cmd += " --bandwidth " + str( bandwidth )
1611 if lambdaAlloc:
1612 cmd += " --lambda "
1613 if ipProto:
1614 cmd += " --ipProto " + str( ipProto )
1615 if ipSrc:
1616 cmd += " --ipSrc " + str( ipSrc )
1617 if ipDst:
1618 cmd += " --ipDst " + str( ipDst )
1619 if tcpSrc:
1620 cmd += " --tcpSrc " + str( tcpSrc )
1621 if tcpDst:
1622 cmd += " --tcpDst " + str( tcpDst )
1623 if setEthSrc:
1624 cmd += " --setEthSrc " + str( setEthSrc )
1625 if setEthDst:
1626 cmd += " --setEthDst " + str( setEthDst )
1627 if vlanId:
1628 cmd += " -v " + str( vlanId )
1629 if setVlan:
1630 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001631 if partial:
1632 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001633 if encap:
1634 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001635
kelvin8ec71442015-01-15 16:57:00 -08001636 # Check whether the user appended the port
1637 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001638
1639 if portIngressList is None:
1640 for ingressDevice in ingressDeviceList:
1641 if "/" in ingressDevice:
1642 cmd += " " + str( ingressDevice )
1643 else:
1644 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001645 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001646 # TODO: perhaps more meaningful return
1647 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001648 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001649 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001650 for ingressDevice, portIngress in zip( ingressDeviceList,
1651 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001652 cmd += " " + \
1653 str( ingressDevice ) + "/" +\
1654 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001655 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001656 main.log.error( "Device list and port list does not " +
1657 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001658 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001659 if "/" in egressDevice:
1660 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001661 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001662 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001663 main.log.error( "You must specify " +
1664 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001665 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001666
kelvin8ec71442015-01-15 16:57:00 -08001667 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001668 str( egressDevice ) + "/" +\
1669 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001670 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001671 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001672 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001673 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001674 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001675 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001676 "intent" )
1677 return None
shahshreyad0c80432014-12-04 16:56:05 -08001678 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001679 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001680 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001681 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001682 else:
1683 main.log.error( "Error, intent ID not found" )
1684 return None
Jon Hallc6793552016-01-19 14:18:37 -08001685 except AssertionError:
1686 main.log.exception( "" )
1687 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001688 except TypeError:
1689 main.log.exception( self.name + ": Object not as expected" )
1690 return None
1691 except pexpect.EOF:
1692 main.log.error( self.name + ": EOF exception found" )
1693 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001694 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001695 except Exception:
1696 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001697 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001698
1699 def addSinglepointToMultipointIntent(
1700 self,
1701 ingressDevice,
1702 egressDeviceList,
1703 portIngress="",
1704 portEgressList=None,
1705 ethType="",
1706 ethSrc="",
1707 ethDst="",
1708 bandwidth="",
1709 lambdaAlloc=False,
1710 ipProto="",
1711 ipSrc="",
1712 ipDst="",
1713 tcpSrc="",
1714 tcpDst="",
1715 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001716 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001717 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001718 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001719 partial=False,
1720 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001721 """
1722 Note:
1723 This function assumes the format of all egress devices
1724 is same. That is, all egress devices include port numbers
1725 with a "/" or all egress devices could specify device
1726 ids and port numbers seperately.
1727 Required:
1728 * EgressDeviceList: List of device ids of egress device
1729 ( Atleast 2 eress devices required in the list )
1730 * ingressDevice: device id of ingress device
1731 Optional:
1732 * ethType: specify ethType
1733 * ethSrc: specify ethSrc ( i.e. src mac addr )
1734 * ethDst: specify ethDst ( i.e. dst mac addr )
1735 * bandwidth: specify bandwidth capacity of link
1736 * lambdaAlloc: if True, intent will allocate lambda
1737 for the specified intent
1738 * ipProto: specify ip protocol
1739 * ipSrc: specify ip source address
1740 * ipDst: specify ip destination address
1741 * tcpSrc: specify tcp source port
1742 * tcpDst: specify tcp destination port
1743 * setEthSrc: action to Rewrite Source MAC Address
1744 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001745 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001746 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001747 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001748 Description:
1749 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1750 specifying device id's and optional fields
1751 Returns:
1752 A string of the intent id or None on error
1753
1754 NOTE: This function may change depending on the
1755 options developers provide for singlepoint-to-multipoint
1756 intent via cli
1757 """
1758 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001759 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001760
Jeremy Songsterff553672016-05-12 17:06:23 -07001761 if ethType:
1762 cmd += " --ethType " + str( ethType )
1763 if ethSrc:
1764 cmd += " --ethSrc " + str( ethSrc )
1765 if ethDst:
1766 cmd += " --ethDst " + str( ethDst )
1767 if bandwidth:
1768 cmd += " --bandwidth " + str( bandwidth )
1769 if lambdaAlloc:
1770 cmd += " --lambda "
1771 if ipProto:
1772 cmd += " --ipProto " + str( ipProto )
1773 if ipSrc:
1774 cmd += " --ipSrc " + str( ipSrc )
1775 if ipDst:
1776 cmd += " --ipDst " + str( ipDst )
1777 if tcpSrc:
1778 cmd += " --tcpSrc " + str( tcpSrc )
1779 if tcpDst:
1780 cmd += " --tcpDst " + str( tcpDst )
1781 if setEthSrc:
1782 cmd += " --setEthSrc " + str( setEthSrc )
1783 if setEthDst:
1784 cmd += " --setEthDst " + str( setEthDst )
1785 if vlanId:
1786 cmd += " -v " + str( vlanId )
1787 if setVlan:
1788 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001789 if partial:
1790 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001791 if encap:
1792 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001793
1794 # Check whether the user appended the port
1795 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001796
kelvin-onlabb9408212015-04-01 13:34:04 -07001797 if "/" in ingressDevice:
1798 cmd += " " + str( ingressDevice )
1799 else:
1800 if not portIngress:
1801 main.log.error( "You must specify " +
1802 "the Ingress port" )
1803 return main.FALSE
1804
1805 cmd += " " +\
1806 str( ingressDevice ) + "/" +\
1807 str( portIngress )
1808
1809 if portEgressList is None:
1810 for egressDevice in egressDeviceList:
1811 if "/" in egressDevice:
1812 cmd += " " + str( egressDevice )
1813 else:
1814 main.log.error( "You must specify " +
1815 "the egress port" )
1816 # TODO: perhaps more meaningful return
1817 return main.FALSE
1818 else:
1819 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001820 for egressDevice, portEgress in zip( egressDeviceList,
1821 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001822 cmd += " " + \
1823 str( egressDevice ) + "/" +\
1824 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001825 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001826 main.log.error( "Device list and port list does not " +
1827 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001828 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001829 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001830 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001831 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001832 # If error, return error message
1833 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001834 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001835 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001836 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001837 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001838 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001839 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001840 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001841 else:
1842 main.log.error( "Error, intent ID not found" )
1843 return None
Jon Hallc6793552016-01-19 14:18:37 -08001844 except AssertionError:
1845 main.log.exception( "" )
1846 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001847 except TypeError:
1848 main.log.exception( self.name + ": Object not as expected" )
1849 return None
shahshreyad0c80432014-12-04 16:56:05 -08001850 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001851 main.log.error( self.name + ": EOF exception found" )
1852 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001853 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001854 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001855 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001856 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001857
Hari Krishna9e232602015-04-13 17:29:08 -07001858 def addMplsIntent(
1859 self,
1860 ingressDevice,
1861 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001862 ingressPort="",
1863 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001864 ethType="",
1865 ethSrc="",
1866 ethDst="",
1867 bandwidth="",
1868 lambdaAlloc=False,
1869 ipProto="",
1870 ipSrc="",
1871 ipDst="",
1872 tcpSrc="",
1873 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001874 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001875 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001876 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001877 """
1878 Required:
1879 * ingressDevice: device id of ingress device
1880 * egressDevice: device id of egress device
1881 Optional:
1882 * ethType: specify ethType
1883 * ethSrc: specify ethSrc ( i.e. src mac addr )
1884 * ethDst: specify ethDst ( i.e. dst mac addr )
1885 * bandwidth: specify bandwidth capacity of link
1886 * lambdaAlloc: if True, intent will allocate lambda
1887 for the specified intent
1888 * ipProto: specify ip protocol
1889 * ipSrc: specify ip source address
1890 * ipDst: specify ip destination address
1891 * tcpSrc: specify tcp source port
1892 * tcpDst: specify tcp destination port
1893 * ingressLabel: Ingress MPLS label
1894 * egressLabel: Egress MPLS label
1895 Description:
1896 Adds MPLS intent by
1897 specifying device id's and optional fields
1898 Returns:
1899 A string of the intent id or None on error
1900
1901 NOTE: This function may change depending on the
1902 options developers provide for MPLS
1903 intent via cli
1904 """
1905 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001906 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001907
Jeremy Songsterff553672016-05-12 17:06:23 -07001908 if ethType:
1909 cmd += " --ethType " + str( ethType )
1910 if ethSrc:
1911 cmd += " --ethSrc " + str( ethSrc )
1912 if ethDst:
1913 cmd += " --ethDst " + str( ethDst )
1914 if bandwidth:
1915 cmd += " --bandwidth " + str( bandwidth )
1916 if lambdaAlloc:
1917 cmd += " --lambda "
1918 if ipProto:
1919 cmd += " --ipProto " + str( ipProto )
1920 if ipSrc:
1921 cmd += " --ipSrc " + str( ipSrc )
1922 if ipDst:
1923 cmd += " --ipDst " + str( ipDst )
1924 if tcpSrc:
1925 cmd += " --tcpSrc " + str( tcpSrc )
1926 if tcpDst:
1927 cmd += " --tcpDst " + str( tcpDst )
1928 if ingressLabel:
1929 cmd += " --ingressLabel " + str( ingressLabel )
1930 if egressLabel:
1931 cmd += " --egressLabel " + str( egressLabel )
1932 if priority:
1933 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001934
1935 # Check whether the user appended the port
1936 # or provided it as an input
1937 if "/" in ingressDevice:
1938 cmd += " " + str( ingressDevice )
1939 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001940 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001941 main.log.error( "You must specify the ingress port" )
1942 return None
1943
1944 cmd += " " + \
1945 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001946 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001947
1948 if "/" in egressDevice:
1949 cmd += " " + str( egressDevice )
1950 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001951 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001952 main.log.error( "You must specify the egress port" )
1953 return None
1954
1955 cmd += " " +\
1956 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001957 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001958
1959 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001960 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001961 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001962 # If error, return error message
1963 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001964 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07001965 return None
1966 else:
1967 # TODO: print out all the options in this message?
1968 main.log.info( "MPLS intent installed between " +
1969 str( ingressDevice ) + " and " +
1970 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001971 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07001972 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001973 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07001974 else:
1975 main.log.error( "Error, intent ID not found" )
1976 return None
Jon Hallc6793552016-01-19 14:18:37 -08001977 except AssertionError:
1978 main.log.exception( "" )
1979 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001980 except TypeError:
1981 main.log.exception( self.name + ": Object not as expected" )
1982 return None
1983 except pexpect.EOF:
1984 main.log.error( self.name + ": EOF exception found" )
1985 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001986 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001987 except Exception:
1988 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001989 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001990
Jon Hallefbd9792015-03-05 16:11:36 -08001991 def removeIntent( self, intentId, app='org.onosproject.cli',
1992 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001993 """
shahshreya1c818fc2015-02-26 13:44:08 -08001994 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001995 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001996 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001997 -p or --purge: Purge the intent from the store after removal
1998
Jon Halle3f39ff2015-01-13 11:50:53 -08001999 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002000 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002001 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002002 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002003 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002004 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002005 if purge:
2006 cmdStr += " -p"
2007 if sync:
2008 cmdStr += " -s"
2009
2010 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002011 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002012 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002013 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002014 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002015 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002016 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002017 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002018 # TODO: Should this be main.TRUE
2019 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002020 except AssertionError:
2021 main.log.exception( "" )
2022 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002023 except TypeError:
2024 main.log.exception( self.name + ": Object not as expected" )
2025 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002026 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002027 main.log.error( self.name + ": EOF exception found" )
2028 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002029 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002030 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002031 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002032 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002033
YPZhangfebf7302016-05-24 16:45:56 -07002034 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002035 """
2036 Description:
2037 Remove all the intents
2038 Optional args:-
2039 -s or --sync: Waits for the removal before returning
2040 -p or --purge: Purge the intent from the store after removal
2041 Returns:
2042 Returns main.TRUE if all intents are removed, otherwise returns
2043 main.FALSE; Returns None for exception
2044 """
2045 try:
2046 cmdStr = "remove-intent"
2047 if purge:
2048 cmdStr += " -p"
2049 if sync:
2050 cmdStr += " -s"
2051
2052 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002053 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002054 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002055 assert "Command not found:" not in handle, handle
2056 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002057 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002058 return main.FALSE
2059 else:
2060 return main.TRUE
2061 except AssertionError:
2062 main.log.exception( "" )
2063 return None
2064 except TypeError:
2065 main.log.exception( self.name + ": Object not as expected" )
2066 return None
2067 except pexpect.EOF:
2068 main.log.error( self.name + ": EOF exception found" )
2069 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002070 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002071 except Exception:
2072 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002073 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002074
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002075 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002076 """
2077 Purges all WITHDRAWN Intents
2078 """
2079 try:
2080 cmdStr = "purge-intents"
2081 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002082 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002083 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002084 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002085 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002086 return main.FALSE
2087 else:
2088 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002089 except AssertionError:
2090 main.log.exception( "" )
2091 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002092 except TypeError:
2093 main.log.exception( self.name + ": Object not as expected" )
2094 return None
2095 except pexpect.EOF:
2096 main.log.error( self.name + ": EOF exception found" )
2097 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002098 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002099 except Exception:
2100 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002101 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002102
Devin Lime6fe3c42017-10-18 16:28:40 -07002103 def wipeout( self ):
2104 """
2105 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2106 """
2107 try:
2108 cmdStr = "wipe-out please"
2109 handle = self.sendline( cmdStr, timeout=60 )
2110 assert handle is not None, "Error in sendline"
2111 assert "Command not found:" not in handle, handle
2112 return main.TRUE
2113 except AssertionError:
2114 main.log.exception( "" )
2115 return None
2116 except TypeError:
2117 main.log.exception( self.name + ": Object not as expected" )
2118 return None
2119 except pexpect.EOF:
2120 main.log.error( self.name + ": EOF exception found" )
2121 main.log.error( self.name + ": " + self.handle.before )
2122 main.cleanAndExit()
2123 except Exception:
2124 main.log.exception( self.name + ": Uncaught exception!" )
2125 main.cleanAndExit()
2126
kelvin-onlabd3b64892015-01-20 13:26:24 -08002127 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002128 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002129 NOTE: This method should be used after installing application:
2130 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002131 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002132 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002133 Description:
2134 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002135 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002136 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002137 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002138 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002139 cmdStr += " -j"
2140 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002141 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002142 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002143 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002144 except AssertionError:
2145 main.log.exception( "" )
2146 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002147 except TypeError:
2148 main.log.exception( self.name + ": Object not as expected" )
2149 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002150 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002151 main.log.error( self.name + ": EOF exception found" )
2152 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002153 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002154 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002155 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002156 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002157
pingping-lin54b03372015-08-13 14:43:10 -07002158 def ipv4RouteNumber( self ):
2159 """
2160 NOTE: This method should be used after installing application:
2161 onos-app-sdnip
2162 Description:
2163 Obtain the total IPv4 routes number in the system
2164 """
2165 try:
Pratik Parab57963572017-05-09 11:37:54 -07002166 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002167 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002168 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002169 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002170 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002171 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002172 except AssertionError:
2173 main.log.exception( "" )
2174 return None
2175 except ( TypeError, ValueError ):
2176 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002177 return None
2178 except pexpect.EOF:
2179 main.log.error( self.name + ": EOF exception found" )
2180 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002181 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002182 except Exception:
2183 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002184 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002185
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002186 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002187 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002188 """
2189 Description:
2190 Obtain Bandwidth Allocation Information from ONOS cli.
2191 """
2192 try:
2193 cmdStr = "allocations"
2194 if jsonFormat:
2195 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002196 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002197 assert handle is not None, "Error in sendline"
2198 assert "Command not found:" not in handle, handle
2199 return handle
2200 except AssertionError:
2201 main.log.exception( "" )
2202 return None
2203 except ( TypeError, ValueError ):
2204 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2205 return None
2206 except pexpect.EOF:
2207 main.log.error( self.name + ": EOF exception found" )
2208 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002209 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002210 except Exception:
2211 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002212 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002213
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002214 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002215 """
andrewonlabe6745342014-10-17 14:29:13 -04002216 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002217 Obtain intents from the ONOS cli.
2218 Optional:
2219 * jsonFormat: Enable output formatting in json, default to True
2220 * summary: Whether only output the intent summary, defaults to False
2221 * type: Only output a certain type of intent. This options is valid
2222 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002223 """
andrewonlabe6745342014-10-17 14:29:13 -04002224 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002225 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002226 if summary:
2227 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002228 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002229 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002230 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002231 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002232 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002233 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002234 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002235 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002236 else:
Jon Hallff566d52016-01-15 14:45:36 -08002237 intentType = ""
2238 # IF we want the summary of a specific intent type
2239 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002240 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002241 if intentType in jsonResult.keys():
2242 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002243 else:
Jon Hallff566d52016-01-15 14:45:36 -08002244 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002245 return handle
2246 else:
2247 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002248 except AssertionError:
2249 main.log.exception( "" )
2250 return None
2251 except ( TypeError, ValueError ):
2252 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002253 return None
2254 except pexpect.EOF:
2255 main.log.error( self.name + ": EOF exception found" )
2256 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002257 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002258 except Exception:
2259 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002260 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002261
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002262 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002263 """
You Wangfdcbfc42016-05-16 12:16:53 -07002264 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002265 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002266 list of intent IDs.
2267 Parameters:
2268 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002269 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002270 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002271 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002272 accepted.
2273 Returns a list of dictionaries if a list of intent IDs is accepted,
2274 and each dictionary maps 'id' to the Intent ID and 'state' to
2275 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002276 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002277
kelvin-onlab54400a92015-02-26 18:05:51 -08002278 try:
2279 state = "State is Undefined"
2280 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002281 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002282 else:
Jon Hallc6793552016-01-19 14:18:37 -08002283 rawJson = intentsJson
2284 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002285 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002286 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002287 if intentsId == intent[ 'id' ]:
2288 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002289 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002290 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002291 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002292 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002293 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002294 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002295 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002296 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002297 for intent in parsedIntentsJson:
2298 if intentsId[ i ] == intent[ 'id' ]:
2299 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002300 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002301 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002302 break
Jon Hallefbd9792015-03-05 16:11:36 -08002303 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002304 main.log.warn( "Could not find all intents in ONOS output" )
2305 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002306 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002307 else:
Jon Hall53158082017-05-18 11:17:00 -07002308 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002309 return None
Jon Hallc6793552016-01-19 14:18:37 -08002310 except ( TypeError, ValueError ):
2311 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002312 return None
2313 except pexpect.EOF:
2314 main.log.error( self.name + ": EOF exception found" )
2315 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002316 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002317 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002318 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002319 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002320
Jon Hallf539eb92017-05-22 17:18:42 -07002321 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002322 """
2323 Description:
2324 Check intents state
2325 Required:
2326 intentsId - List of intents ID to be checked
2327 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002328 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002329 state in the list.
2330 *NOTE: You can pass in a list of expected state,
2331 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002332 Return:
Jon Hall53158082017-05-18 11:17:00 -07002333 Returns main.TRUE only if all intent are the same as expected states,
2334 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002335 """
2336 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002337 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002338 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002339
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002340 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002341 intentsDict = []
2342 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002343 if isinstance( intentsId, types.StringType ) \
2344 and intent.get( 'id' ) == intentsId:
2345 intentsDict.append( intent )
2346 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002347 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002348 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002349
2350 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002351 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002352 "getting intents state" )
2353 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002354
2355 if isinstance( expectedState, types.StringType ):
2356 for intents in intentsDict:
2357 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002358 main.log.debug( self.name + " : Intent ID - " +
2359 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002360 " actual state = " +
2361 intents.get( 'state' )
2362 + " does not equal expected state = "
2363 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002364 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002365 elif isinstance( expectedState, types.ListType ):
2366 for intents in intentsDict:
2367 if not any( state == intents.get( 'state' ) for state in
2368 expectedState ):
2369 main.log.debug( self.name + " : Intent ID - " +
2370 intents.get( 'id' ) +
2371 " actual state = " +
2372 intents.get( 'state' ) +
2373 " does not equal expected states = "
2374 + str( expectedState ) )
2375 returnValue = main.FALSE
2376
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002377 if returnValue == main.TRUE:
2378 main.log.info( self.name + ": All " +
2379 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002380 " intents are in " + str( expectedState ) +
2381 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002382 return returnValue
2383 except TypeError:
2384 main.log.exception( self.name + ": Object not as expected" )
2385 return None
2386 except pexpect.EOF:
2387 main.log.error( self.name + ": EOF exception found" )
2388 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002389 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002390 except Exception:
2391 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002392 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002393
Jon Hallf539eb92017-05-22 17:18:42 -07002394 def compareBandwidthAllocations( self, expectedAllocations ):
2395 """
2396 Description:
2397 Compare the allocated bandwidth with the given allocations
2398 Required:
2399 expectedAllocations - The expected ONOS output of the allocations command
2400 Return:
2401 Returns main.TRUE only if all intent are the same as expected states,
2402 otherwise returns main.FALSE.
2403 """
2404 # FIXME: Convert these string comparisons to object comparisons
2405 try:
2406 returnValue = main.TRUE
2407 bandwidthFailed = False
2408 rawAlloc = self.allocations()
2409 expectedFormat = StringIO( expectedAllocations )
2410 ONOSOutput = StringIO( rawAlloc )
2411 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2412 str( expectedFormat ) ) )
2413
2414 for actual, expected in izip( ONOSOutput, expectedFormat ):
2415 actual = actual.rstrip()
2416 expected = expected.rstrip()
2417 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2418 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002419 marker1 = actual.find( 'allocated' )
2420 m1 = actual[ :marker1 ]
2421 marker2 = expected.find( 'allocated' )
2422 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002423 if m1 != m2:
2424 bandwidthFailed = True
2425 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2426 bandwidthFailed = True
2427 expectedFormat.close()
2428 ONOSOutput.close()
2429
2430 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002431 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002432 returnValue = main.FALSE
2433 return returnValue
2434 except TypeError:
2435 main.log.exception( self.name + ": Object not as expected" )
2436 return None
2437 except pexpect.EOF:
2438 main.log.error( self.name + ": EOF exception found" )
2439 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002440 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002441 except Exception:
2442 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002443 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002444
You Wang66518af2016-05-16 15:32:59 -07002445 def compareIntent( self, intentDict ):
2446 """
2447 Description:
2448 Compare the intent ids and states provided in the argument with all intents in ONOS
2449 Return:
2450 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2451 Arguments:
2452 intentDict: a dictionary which maps intent ids to intent states
2453 """
2454 try:
2455 intentsRaw = self.intents()
2456 intentsJson = json.loads( intentsRaw )
2457 intentDictONOS = {}
2458 for intent in intentsJson:
2459 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002460 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002461 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002462 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002463 str( len( intentDict ) ) + " expected and " +
2464 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002465 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002466 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002467 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002468 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2469 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002470 else:
2471 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2472 main.log.debug( self.name + ": intent ID - " + intentID +
2473 " expected state is " + intentDict[ intentID ] +
2474 " but actual state is " + intentDictONOS[ intentID ] )
2475 returnValue = main.FALSE
2476 intentDictONOS.pop( intentID )
2477 if len( intentDictONOS ) > 0:
2478 returnValue = main.FALSE
2479 for intentID in intentDictONOS.keys():
2480 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002481 if returnValue == main.TRUE:
2482 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2483 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002484 except KeyError:
2485 main.log.exception( self.name + ": KeyError exception found" )
2486 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002487 except ( TypeError, ValueError ):
2488 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002489 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002490 except pexpect.EOF:
2491 main.log.error( self.name + ": EOF exception found" )
2492 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002493 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002494 except Exception:
2495 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002496 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002497
YPZhang14a4aa92016-07-15 13:37:15 -07002498 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002499 """
2500 Description:
2501 Check the number of installed intents.
2502 Optional:
2503 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002504 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002505 Return:
2506 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2507 , otherwise, returns main.FALSE.
2508 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002509
GlennRCed771242016-01-13 17:02:47 -08002510 try:
2511 cmd = "intents -s -j"
2512
2513 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002514 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002515 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002516 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002517 response = json.loads( response )
2518
2519 # get total and installed number, see if they are match
2520 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002521 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002522 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2523 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002524 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002525 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2526 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002527 return main.FALSE
2528
Jon Hallc6793552016-01-19 14:18:37 -08002529 except ( TypeError, ValueError ):
2530 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002531 return None
2532 except pexpect.EOF:
2533 main.log.error( self.name + ": EOF exception found" )
2534 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002535 if noExit:
2536 return main.FALSE
2537 else:
Devin Lim44075962017-08-11 10:56:37 -07002538 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002539 except pexpect.TIMEOUT:
2540 main.log.error( self.name + ": ONOS timeout" )
2541 return None
GlennRCed771242016-01-13 17:02:47 -08002542 except Exception:
2543 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002544 if noExit:
2545 return main.FALSE
2546 else:
Devin Lim44075962017-08-11 10:56:37 -07002547 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002548
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002549 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002550 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002551 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002552 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002553 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002554 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002555 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002556 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002557 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002558 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002559 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002560 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002561 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002562 cmdStr += " -n"
2563 cmdStr += " " + state
2564 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002565 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002566 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002567 assert "Command not found:" not in handle, handle
2568 if re.search( "Error:", handle ):
2569 main.log.error( self.name + ": flows() response: " +
2570 str( handle ) )
2571 return handle
2572 except AssertionError:
2573 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002574 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002575 except TypeError:
2576 main.log.exception( self.name + ": Object not as expected" )
2577 return None
Jon Hallc6793552016-01-19 14:18:37 -08002578 except pexpect.TIMEOUT:
2579 main.log.error( self.name + ": ONOS timeout" )
2580 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002581 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002582 main.log.error( self.name + ": EOF exception found" )
2583 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002584 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002585 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002586 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002587 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002588
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002589 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002590 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002591 count = int( count ) if count else 0
steven30801a0cc1422019-01-26 10:06:51 +08002592 main.log.debug( "found {} flows".format( count ) )
Jon Halle0f0b342017-04-18 11:43:47 -07002593 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002594
Jon Halle0f0b342017-04-18 11:43:47 -07002595 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002596 """
2597 Description:
GlennRCed771242016-01-13 17:02:47 -08002598 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002599 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2600 if the count of those states is 0, which means all current flows
2601 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002602 Optional:
GlennRCed771242016-01-13 17:02:47 -08002603 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002604 Return:
2605 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002606 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002607 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002608 """
2609 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002610 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002611 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002612 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002613 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002614 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002615 if rawFlows:
2616 # if we didn't get flows or flows function return None, we should return
2617 # main.Flase
2618 checkedStates.append( json.loads( rawFlows ) )
2619 else:
2620 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002621 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002622 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002623 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002624 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002625 except TypeError:
2626 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002627 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002628
GlennRCed771242016-01-13 17:02:47 -08002629 # We want to count PENDING_ADD if isPENDING is true
2630 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002631 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002632 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002633 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002634 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002635 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002636 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002637 except ( TypeError, ValueError ):
2638 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002639 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002640
YPZhang240842b2016-05-17 12:00:50 -07002641 except AssertionError:
2642 main.log.exception( "" )
2643 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002644 except pexpect.TIMEOUT:
2645 main.log.error( self.name + ": ONOS timeout" )
2646 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002647 except pexpect.EOF:
2648 main.log.error( self.name + ": EOF exception found" )
2649 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002650 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002651 except Exception:
2652 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002653 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002654
GlennRCed771242016-01-13 17:02:47 -08002655 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002656 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002657 """
andrewonlab87852b02014-11-19 18:44:19 -05002658 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002659 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002660 a specific point-to-point intent definition
2661 Required:
GlennRCed771242016-01-13 17:02:47 -08002662 * ingress: specify source dpid
2663 * egress: specify destination dpid
2664 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002665 Optional:
GlennRCed771242016-01-13 17:02:47 -08002666 * offset: the keyOffset is where the next batch of intents
2667 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002668 * noExit: If set to True, TestON will not exit if any error when issus command
2669 * getResponse: If set to True, function will return ONOS response.
2670
GlennRCed771242016-01-13 17:02:47 -08002671 Returns: If failed to push test intents, it will returen None,
2672 if successful, return true.
2673 Timeout expection will return None,
2674 TypeError will return false
2675 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002676 """
andrewonlab87852b02014-11-19 18:44:19 -05002677 try:
GlennRCed771242016-01-13 17:02:47 -08002678 if background:
2679 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002680 else:
GlennRCed771242016-01-13 17:02:47 -08002681 back = ""
2682 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002683 ingress,
2684 egress,
2685 batchSize,
2686 offset,
2687 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002688 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002689 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002690 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002691 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002692 if getResponse:
2693 return response
2694
GlennRCed771242016-01-13 17:02:47 -08002695 # TODO: We should handle if there is failure in installation
2696 return main.TRUE
2697
Jon Hallc6793552016-01-19 14:18:37 -08002698 except AssertionError:
2699 main.log.exception( "" )
2700 return None
GlennRCed771242016-01-13 17:02:47 -08002701 except pexpect.TIMEOUT:
2702 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002703 return None
andrewonlab87852b02014-11-19 18:44:19 -05002704 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002705 main.log.error( self.name + ": EOF exception found" )
2706 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002707 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002708 except TypeError:
2709 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002710 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002711 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002712 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002713 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002714
YPZhangebf9eb52016-05-12 15:20:24 -07002715 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002716 """
2717 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002718 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002719 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002720 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002721 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002722 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002723
YPZhangb5d3f832016-01-23 22:54:26 -08002724 try:
YPZhange3109a72016-02-02 11:25:37 -08002725 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002726 cmd = "flows -c added"
2727 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2728 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002729 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002730 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002731 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002732 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002733 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002734 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002735 return None
2736 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002737
You Wangd3cb2ce2016-05-16 14:01:24 -07002738 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002739 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002740 return None
2741 except pexpect.EOF:
2742 main.log.error( self.name + ": EOF exception found" )
2743 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002744 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002745 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002746 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002747 except pexpect.TIMEOUT:
2748 main.log.error( self.name + ": ONOS timeout" )
2749 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002750 except Exception:
2751 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002752 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002753 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002754 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002755
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002756 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002757 """
2758 Description:
2759 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002760 Optional:
2761 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002762 Return:
2763 The number of intents
2764 """
2765 try:
2766 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002767 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002768 if response is None:
2769 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002770 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002771 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002772 except ( TypeError, ValueError ):
2773 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002774 return None
2775 except pexpect.EOF:
2776 main.log.error( self.name + ": EOF exception found" )
2777 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002778 if noExit:
2779 return -1
2780 else:
Devin Lim44075962017-08-11 10:56:37 -07002781 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002782 except Exception:
2783 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002784 if noExit:
2785 return -1
2786 else:
Devin Lim44075962017-08-11 10:56:37 -07002787 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002788
kelvin-onlabd3b64892015-01-20 13:26:24 -08002789 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002790 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002791 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002792 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002793 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002794 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002795 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002796 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002797 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002798 cmdStr += " -j"
2799 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002800 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002801 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002802 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002803 except AssertionError:
2804 main.log.exception( "" )
2805 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002806 except TypeError:
2807 main.log.exception( self.name + ": Object not as expected" )
2808 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002809 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002810 main.log.error( self.name + ": EOF exception found" )
2811 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002812 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002813 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002814 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002815 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002816
kelvin-onlabd3b64892015-01-20 13:26:24 -08002817 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002818 """
2819 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002820 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002821 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002822 """
andrewonlab867212a2014-10-22 20:13:38 -04002823 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002824 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002825 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002826 cmdStr += " -j"
2827 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002828 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002829 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002830 if handle:
2831 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002832 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002833 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002834 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002835 else:
2836 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002837 except AssertionError:
2838 main.log.exception( "" )
2839 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002840 except TypeError:
2841 main.log.exception( self.name + ": Object not as expected" )
2842 return None
andrewonlab867212a2014-10-22 20:13:38 -04002843 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002844 main.log.error( self.name + ": EOF exception found" )
2845 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002846 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002847 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002848 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002849 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002850
kelvin8ec71442015-01-15 16:57:00 -08002851 # Wrapper functions ****************
2852 # Wrapper functions use existing driver
2853 # functions and extends their use case.
2854 # For example, we may use the output of
2855 # a normal driver function, and parse it
2856 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002857
kelvin-onlabd3b64892015-01-20 13:26:24 -08002858 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002859 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002860 Description:
2861 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002862 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002863 try:
kelvin8ec71442015-01-15 16:57:00 -08002864 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002865 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002866 if intentsStr is None:
2867 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002868 # Convert to a dictionary
2869 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002870 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002871 for intent in intents:
2872 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002873 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002874 except TypeError:
2875 main.log.exception( self.name + ": Object not as expected" )
2876 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002877 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002878 main.log.error( self.name + ": EOF exception found" )
2879 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002880 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002881 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002882 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002883 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002884
You Wang3c276252016-09-21 15:21:36 -07002885 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002886 """
2887 Determine the number of flow rules for the given device id that are
2888 in the added state
You Wang3c276252016-09-21 15:21:36 -07002889 Params:
2890 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002891 """
2892 try:
You Wang3c276252016-09-21 15:21:36 -07002893 if core:
2894 cmdStr = "flows any " + str( deviceId ) + " | " +\
2895 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2896 else:
2897 cmdStr = "flows any " + str( deviceId ) + " | " +\
2898 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002899 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002900 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002901 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002902 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002903 except AssertionError:
2904 main.log.exception( "" )
2905 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002906 except pexpect.EOF:
2907 main.log.error( self.name + ": EOF exception found" )
2908 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002909 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002910 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002911 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002912 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002913
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002914 def groupAddedCount( self, deviceId, core=False ):
2915 """
2916 Determine the number of group rules for the given device id that are
2917 in the added state
2918 Params:
2919 core: if True, only return the number of core groups added
2920 """
2921 try:
2922 if core:
2923 cmdStr = "groups any " + str( deviceId ) + " | " +\
2924 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2925 else:
2926 cmdStr = "groups any " + str( deviceId ) + " | " +\
2927 "grep 'state=ADDED' | wc -l"
2928 handle = self.sendline( cmdStr )
2929 assert handle is not None, "Error in sendline"
2930 assert "Command not found:" not in handle, handle
2931 return handle
2932 except AssertionError:
2933 main.log.exception( "" )
2934 return None
2935 except pexpect.EOF:
2936 main.log.error( self.name + ": EOF exception found" )
2937 main.log.error( self.name + ": " + self.handle.before )
2938 main.cleanAndExit()
2939 except Exception:
2940 main.log.exception( self.name + ": Uncaught exception!" )
2941 main.cleanAndExit()
2942
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002943 def addStaticRoute( self, subnet, intf):
2944 """
2945 Adds a static route to onos.
2946 Params:
2947 subnet: The subnet reaching through this route
2948 intf: The interface this route is reachable through
2949 """
2950 try:
2951 cmdStr = "route-add " + subnet + " " + intf
2952 handle = self.sendline( cmdStr )
2953 assert handle is not None, "Error in sendline"
2954 assert "Command not found:" not in handle, handle
2955 return handle
2956 except AssertionError:
2957 main.log.exception( "" )
2958 return None
2959 except pexpect.EOF:
2960 main.log.error( self.name + ": EOF exception found" )
2961 main.log.error( self.name + ": " + self.handle.before )
2962 main.cleanAndExit()
2963 except Exception:
2964 main.log.exception( self.name + ": Uncaught exception!" )
2965 main.cleanAndExit()
2966
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002967 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
2968 """
2969 Description:
2970 Check whether the number of groups for the given device id that
2971 are in ADDED state is bigger than minGroupCount.
2972 Required:
2973 * deviceId: device id to check the number of added group rules
2974 Optional:
2975 * minGroupCount: the number of groups to compare
2976 * core: if True, only check the number of core groups added
2977 * comparison: if 0, compare with greater than minFlowCount
2978 * if 1, compare with equal to minFlowCount
2979 Return:
2980 Returns the number of groups if it is bigger than minGroupCount,
2981 returns main.FALSE otherwise.
2982 """
2983 count = self.groupAddedCount( deviceId, core )
2984 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07002985 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002986 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
2987
You Wangc02f3be2018-05-18 12:14:23 -07002988 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002989 """
2990 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07002991 deviceId: Id of the device from which we retrieve groups
2992 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002993 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002994 try:
You Wangc02f3be2018-05-18 12:14:23 -07002995 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
2996 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002997 assert handle is not None, "Error in sendline"
2998 assert "Command not found:" not in handle, handle
2999 return handle
3000 except AssertionError:
3001 main.log.exception( "" )
3002 return None
3003 except TypeError:
3004 main.log.exception( self.name + ": Object not as expected" )
3005 return None
3006 except pexpect.EOF:
3007 main.log.error( self.name + ": EOF exception found" )
3008 main.log.error( self.name + ": " + self.handle.before )
3009 main.cleanAndExit()
3010 except Exception:
3011 main.log.exception( self.name + ": Uncaught exception!" )
3012 main.cleanAndExit()
3013
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003014 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003015 """
3016 Description:
3017 Check whether the number of flow rules for the given device id that
3018 are in ADDED state is bigger than minFlowCount.
3019 Required:
3020 * deviceId: device id to check the number of added flow rules
3021 Optional:
3022 * minFlowCount: the number of flow rules to compare
3023 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003024 * comparison: if 0, compare with greater than minFlowCount
3025 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003026 Return:
3027 Returns the number of flow rules if it is bigger than minFlowCount,
3028 returns main.FALSE otherwise.
3029 """
3030 count = self.flowAddedCount( deviceId, core )
3031 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003032 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003033 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003034
kelvin-onlabd3b64892015-01-20 13:26:24 -08003035 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003036 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003037 Use 'devices' function to obtain list of all devices
3038 and parse the result to obtain a list of all device
3039 id's. Returns this list. Returns empty list if no
3040 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003041 List is ordered sequentially
3042
andrewonlab3e15ead2014-10-15 14:21:34 -04003043 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003044 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003045 the ids. By obtaining the list of device ids on the fly,
3046 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003047 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003048 try:
kelvin8ec71442015-01-15 16:57:00 -08003049 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003050 devicesStr = self.devices( jsonFormat=False )
3051 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003052
kelvin-onlabd3b64892015-01-20 13:26:24 -08003053 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003054 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003055 return idList
kelvin8ec71442015-01-15 16:57:00 -08003056
3057 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003058 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003059 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003060 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003061 # Split list further into arguments before and after string
3062 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003063 # append to idList
3064 for arg in tempList:
3065 idList.append( arg.split( "id=" )[ 1 ] )
3066 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003067
Jon Halld4d4b372015-01-28 16:02:41 -08003068 except TypeError:
3069 main.log.exception( self.name + ": Object not as expected" )
3070 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003071 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003072 main.log.error( self.name + ": EOF exception found" )
3073 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003074 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003075 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003076 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003077 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003078
kelvin-onlabd3b64892015-01-20 13:26:24 -08003079 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003080 """
andrewonlab7c211572014-10-15 16:45:20 -04003081 Uses 'nodes' function to obtain list of all nodes
3082 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003083 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003084 Returns:
3085 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003086 """
andrewonlab7c211572014-10-15 16:45:20 -04003087 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003088 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003089 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003090 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003091 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003092 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003093 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003094 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003095 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003096 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003097 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003098 except ( TypeError, ValueError ):
3099 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003100 return None
andrewonlab7c211572014-10-15 16:45:20 -04003101 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003102 main.log.error( self.name + ": EOF exception found" )
3103 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003104 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003105 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003106 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003107 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003108
kelvin-onlabd3b64892015-01-20 13:26:24 -08003109 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003110 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003111 Return the first device from the devices api whose 'id' contains 'dpid'
3112 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003113 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003114 try:
kelvin8ec71442015-01-15 16:57:00 -08003115 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003116 return None
3117 else:
kelvin8ec71442015-01-15 16:57:00 -08003118 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003119 rawDevices = self.devices()
3120 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003121 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003122 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003123 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3124 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003125 return device
3126 return None
Jon Hallc6793552016-01-19 14:18:37 -08003127 except ( TypeError, ValueError ):
3128 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003129 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003130 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003131 main.log.error( self.name + ": EOF exception found" )
3132 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003133 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003134 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003135 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003136 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003137
You Wang24139872016-05-03 11:48:47 -07003138 def getTopology( self, topologyOutput ):
3139 """
3140 Definition:
3141 Loads a json topology output
3142 Return:
3143 topology = current ONOS topology
3144 """
3145 import json
3146 try:
3147 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003148 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003149 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003150 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003151 except ( TypeError, ValueError ):
3152 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3153 return None
You Wang24139872016-05-03 11:48:47 -07003154 except pexpect.EOF:
3155 main.log.error( self.name + ": EOF exception found" )
3156 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003157 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003158 except Exception:
3159 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003160 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003161
Pier6a0c4de2018-03-18 16:01:30 -07003162 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003163 """
Jon Hallefbd9792015-03-05 16:11:36 -08003164 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003165 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003166 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003167
Flavio Castro82ee2f62016-06-07 15:04:12 -07003168 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003169 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003170 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003171 logLevel = level to log to.
3172 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003173
Jon Hallefbd9792015-03-05 16:11:36 -08003174 Returns: main.TRUE if the number of switches and links are correct,
3175 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003176 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003177 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003178 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003179 try:
You Wang13310252016-07-31 10:56:14 -07003180 summary = self.summary()
3181 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003182 except ( TypeError, ValueError ):
3183 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3184 return main.ERROR
3185 try:
3186 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003187 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003188 return main.ERROR
3189 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003190 # Is the number of switches is what we expected
3191 devices = topology.get( 'devices', False )
3192 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003193 nodes = summary.get( 'nodes', False )
3194 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003195 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003196 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003197 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003198 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003199 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3200 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003201 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003202 output = output + "The number of links and switches match "\
3203 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003204 result = main.TRUE
3205 else:
You Wang24139872016-05-03 11:48:47 -07003206 output = output + \
3207 "The number of links and switches does not match " + \
3208 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003209 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003210 output = output + "\n ONOS sees %i devices" % int( devices )
3211 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003212 if int( numolink ) > 0:
3213 output = output + "and %i links " % int( links )
3214 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003215 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003216 output = output + "and %i controllers " % int( nodes )
3217 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003218 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003219 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003220 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003221 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003222 else:
You Wang24139872016-05-03 11:48:47 -07003223 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003224 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003225 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003226 main.log.error( self.name + ": EOF exception found" )
3227 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003228 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003229 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003230 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003231 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003232
kelvin-onlabd3b64892015-01-20 13:26:24 -08003233 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003234 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003235 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003236 deviceId must be the id of a device as seen in the onos devices command
3237 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003238 role must be either master, standby, or none
3239
Jon Halle3f39ff2015-01-13 11:50:53 -08003240 Returns:
3241 main.TRUE or main.FALSE based on argument verification and
3242 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003243 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003244 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003245 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003246 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003247 cmdStr = "device-role " +\
3248 str( deviceId ) + " " +\
3249 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003250 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003251 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003252 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003253 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003254 if re.search( "Error", handle ):
3255 # end color output to escape any colours
3256 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003257 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003258 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003259 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003260 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003261 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003262 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003263 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003264 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003265 except AssertionError:
3266 main.log.exception( "" )
3267 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003268 except TypeError:
3269 main.log.exception( self.name + ": Object not as expected" )
3270 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003271 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003272 main.log.error( self.name + ": EOF exception found" )
3273 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003274 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003275 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003276 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003277 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003278
kelvin-onlabd3b64892015-01-20 13:26:24 -08003279 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003280 """
Jon Hall0dd09952018-04-19 09:59:11 -07003281 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003282 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003283 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003284 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003285 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003286 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003287 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003288 cmdStr += " -j"
3289 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003290 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003291 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003292 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003293 except AssertionError:
3294 main.log.exception( "" )
3295 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003296 except TypeError:
3297 main.log.exception( self.name + ": Object not as expected" )
3298 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003299 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003300 main.log.error( self.name + ": EOF exception found" )
3301 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003302 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003303 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003304 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003305 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003306
kelvin-onlabd3b64892015-01-20 13:26:24 -08003307 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003308 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003309 CLI command to get the current leader for the Election test application
3310 NOTE: Requires installation of the onos-app-election feature
3311 Returns: Node IP of the leader if one exists
3312 None if none exists
3313 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003314 """
Jon Hall94fd0472014-12-08 11:52:42 -08003315 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003316 cmdStr = "election-test-leader"
3317 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003318 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003319 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003320 # Leader
3321 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003322 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003323 nodeSearch = re.search( leaderPattern, response )
3324 if nodeSearch:
3325 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003326 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003327 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003328 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003329 # no leader
3330 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003331 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003332 nullSearch = re.search( nullPattern, response )
3333 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003334 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003335 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003336 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003337 # error
Jon Hall0e240372018-05-02 11:21:57 -07003338 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003339 ": " + "unexpected response" )
3340 main.log.error( repr( response ) )
3341 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003342 except AssertionError:
3343 main.log.exception( "" )
3344 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003345 except TypeError:
3346 main.log.exception( self.name + ": Object not as expected" )
3347 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003348 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003349 main.log.error( self.name + ": EOF exception found" )
3350 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003351 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003352 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003353 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003354 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003355
kelvin-onlabd3b64892015-01-20 13:26:24 -08003356 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003357 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003358 CLI command to run for leadership of the Election test application.
3359 NOTE: Requires installation of the onos-app-election feature
3360 Returns: Main.TRUE on success
3361 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003362 """
Jon Hall94fd0472014-12-08 11:52:42 -08003363 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003364 cmdStr = "election-test-run"
3365 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003366 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003367 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003368 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003369 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003370 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003371 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003372 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003373 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003374 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003375 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003376 # error
Jon Hall0e240372018-05-02 11:21:57 -07003377 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003378 ": " + "unexpected response" )
3379 main.log.error( repr( response ) )
3380 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003381 except AssertionError:
3382 main.log.exception( "" )
3383 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003384 except TypeError:
3385 main.log.exception( self.name + ": Object not as expected" )
3386 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003387 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003388 main.log.error( self.name + ": EOF exception found" )
3389 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003390 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003391 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003392 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003393 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003394
kelvin-onlabd3b64892015-01-20 13:26:24 -08003395 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003396 """
Jon Hall94fd0472014-12-08 11:52:42 -08003397 * CLI command to withdraw the local node from leadership election for
3398 * the Election test application.
3399 #NOTE: Requires installation of the onos-app-election feature
3400 Returns: Main.TRUE on success
3401 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003402 """
Jon Hall94fd0472014-12-08 11:52:42 -08003403 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003404 cmdStr = "election-test-withdraw"
3405 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003406 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003407 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003408 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003409 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003410 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003411 if re.search( successPattern, response ):
3412 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003413 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003414 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003415 # error
Jon Hall0e240372018-05-02 11:21:57 -07003416 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003417 self.name + ": " + "unexpected response" )
3418 main.log.error( repr( response ) )
3419 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003420 except AssertionError:
3421 main.log.exception( "" )
3422 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003423 except TypeError:
3424 main.log.exception( self.name + ": Object not as expected" )
3425 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003426 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003427 main.log.error( self.name + ": EOF exception found" )
3428 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003429 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003430 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003431 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003432 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003433
kelvin8ec71442015-01-15 16:57:00 -08003434 def getDevicePortsEnabledCount( self, dpid ):
3435 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003436 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003437 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003438 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003439 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003440 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3441 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003442 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003443 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003444 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003445 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003446 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003447 return output
Jon Hallc6793552016-01-19 14:18:37 -08003448 except AssertionError:
3449 main.log.exception( "" )
3450 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003451 except TypeError:
3452 main.log.exception( self.name + ": Object not as expected" )
3453 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003454 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003455 main.log.error( self.name + ": EOF exception found" )
3456 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003457 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003458 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003459 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003460 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003461
kelvin8ec71442015-01-15 16:57:00 -08003462 def getDeviceLinksActiveCount( self, dpid ):
3463 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003464 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003465 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003466 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003467 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003468 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3469 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003470 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003471 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003472 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003473 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003474 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003475 return output
Jon Hallc6793552016-01-19 14:18:37 -08003476 except AssertionError:
3477 main.log.exception( "" )
3478 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003479 except TypeError:
3480 main.log.exception( self.name + ": Object not as expected" )
3481 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003482 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003483 main.log.error( self.name + ": EOF exception found" )
3484 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003485 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003486 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003487 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003488 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003489
kelvin8ec71442015-01-15 16:57:00 -08003490 def getAllIntentIds( self ):
3491 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003492 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003493 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003494 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003495 cmdStr = "onos:intents | grep id="
3496 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003497 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003498 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003499 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003500 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003501 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003502 return output
Jon Hallc6793552016-01-19 14:18:37 -08003503 except AssertionError:
3504 main.log.exception( "" )
3505 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003506 except TypeError:
3507 main.log.exception( self.name + ": Object not as expected" )
3508 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003509 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003510 main.log.error( self.name + ": EOF exception found" )
3511 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003512 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003513 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003514 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003515 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003516
Jon Hall73509952015-02-24 16:42:56 -08003517 def intentSummary( self ):
3518 """
Jon Hallefbd9792015-03-05 16:11:36 -08003519 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003520 """
3521 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003522 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003523 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003524 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003525 states.append( intent.get( 'state', None ) )
3526 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003527 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003528 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003529 except ( TypeError, ValueError ):
3530 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003531 return None
3532 except pexpect.EOF:
3533 main.log.error( self.name + ": EOF exception found" )
3534 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003535 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003536 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003537 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003538 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003539
Jon Hall61282e32015-03-19 11:34:11 -07003540 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003541 """
3542 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003543 Optional argument:
3544 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003545 """
Jon Hall63604932015-02-26 17:09:50 -08003546 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003547 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003548 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003549 cmdStr += " -j"
3550 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003551 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003552 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003553 return output
Jon Hallc6793552016-01-19 14:18:37 -08003554 except AssertionError:
3555 main.log.exception( "" )
3556 return None
Jon Hall63604932015-02-26 17:09:50 -08003557 except TypeError:
3558 main.log.exception( self.name + ": Object not as expected" )
3559 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003560 except pexpect.EOF:
3561 main.log.error( self.name + ": EOF exception found" )
3562 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003563 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003564 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003565 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003566 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003567
acsmarsa4a4d1e2015-07-10 16:01:24 -07003568 def leaderCandidates( self, jsonFormat=True ):
3569 """
3570 Returns the output of the leaders -c command.
3571 Optional argument:
3572 * jsonFormat - boolean indicating if you want output in json
3573 """
3574 try:
3575 cmdStr = "onos:leaders -c"
3576 if jsonFormat:
3577 cmdStr += " -j"
3578 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003579 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003580 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003581 return output
Jon Hallc6793552016-01-19 14:18:37 -08003582 except AssertionError:
3583 main.log.exception( "" )
3584 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003585 except TypeError:
3586 main.log.exception( self.name + ": Object not as expected" )
3587 return None
3588 except pexpect.EOF:
3589 main.log.error( self.name + ": EOF exception found" )
3590 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003591 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003592 except Exception:
3593 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003594 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003595
Jon Hallc6793552016-01-19 14:18:37 -08003596 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003597 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003598 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003599 topic parameter and an empty list if the topic doesn't exist
3600 If no leader is elected leader in the returned list will be "none"
3601 Returns None if there is a type error processing the json object
3602 """
3603 try:
Jon Hall6e709752016-02-01 13:38:46 -08003604 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003605 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003606 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003607 assert "Command not found:" not in rawOutput, rawOutput
3608 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003609 results = []
3610 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003611 if dict[ "topic" ] == topic:
3612 leader = dict[ "leader" ]
3613 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003614 results.append( leader )
3615 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003616 return results
Jon Hallc6793552016-01-19 14:18:37 -08003617 except AssertionError:
3618 main.log.exception( "" )
3619 return None
3620 except ( TypeError, ValueError ):
3621 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003622 return None
3623 except pexpect.EOF:
3624 main.log.error( self.name + ": EOF exception found" )
3625 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003626 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003627 except Exception:
3628 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003629 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003630
Jon Hall61282e32015-03-19 11:34:11 -07003631 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003632 """
3633 Returns the output of the intent Pending map.
3634 """
Jon Hall63604932015-02-26 17:09:50 -08003635 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003636 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003637 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003638 cmdStr += " -j"
3639 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003640 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003641 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003642 return output
Jon Hallc6793552016-01-19 14:18:37 -08003643 except AssertionError:
3644 main.log.exception( "" )
3645 return None
Jon Hall63604932015-02-26 17:09:50 -08003646 except TypeError:
3647 main.log.exception( self.name + ": Object not as expected" )
3648 return None
3649 except pexpect.EOF:
3650 main.log.error( self.name + ": EOF exception found" )
3651 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003652 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003653 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003654 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003655 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003656
Jon Hall2c8959e2016-12-16 12:17:34 -08003657 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003658 """
3659 Returns the output of the raft partitions command for ONOS.
3660 """
Jon Hall61282e32015-03-19 11:34:11 -07003661 # Sample JSON
3662 # {
3663 # "leader": "tcp://10.128.30.11:7238",
3664 # "members": [
3665 # "tcp://10.128.30.11:7238",
3666 # "tcp://10.128.30.17:7238",
3667 # "tcp://10.128.30.13:7238",
3668 # ],
3669 # "name": "p1",
3670 # "term": 3
3671 # },
Jon Hall63604932015-02-26 17:09:50 -08003672 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003673 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003674 if candidates:
3675 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003676 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003677 cmdStr += " -j"
3678 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003679 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003680 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003681 return output
Jon Hallc6793552016-01-19 14:18:37 -08003682 except AssertionError:
3683 main.log.exception( "" )
3684 return None
Jon Hall63604932015-02-26 17:09:50 -08003685 except TypeError:
3686 main.log.exception( self.name + ": Object not as expected" )
3687 return None
3688 except pexpect.EOF:
3689 main.log.error( self.name + ": EOF exception found" )
3690 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003691 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003692 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003693 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003694 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003695
Jon Halle9f909e2016-09-23 10:43:12 -07003696 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003697 """
3698 Returns the output of the apps command for ONOS. This command lists
3699 information about installed ONOS applications
3700 """
3701 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003702 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003703 # "description":"ONOS OpenFlow protocol southbound providers",
3704 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003705 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003706 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003707 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003708 if summary:
3709 cmdStr += " -s"
3710 if active:
3711 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003712 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003713 cmdStr += " -j"
3714 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003715 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003716 assert "Command not found:" not in output, output
3717 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003718 return output
Jon Hallbe379602015-03-24 13:39:32 -07003719 # FIXME: look at specific exceptions/Errors
3720 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003721 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003722 return None
3723 except TypeError:
3724 main.log.exception( self.name + ": Object not as expected" )
3725 return None
3726 except pexpect.EOF:
3727 main.log.error( self.name + ": EOF exception found" )
3728 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003729 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003730 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003731 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003732 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003733
You Wangcdc51fe2018-08-12 17:14:56 -07003734 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003735 """
3736 Uses the onos:apps cli command to return the status of an application.
3737 Returns:
3738 "ACTIVE" - If app is installed and activated
3739 "INSTALLED" - If app is installed and deactivated
3740 "UNINSTALLED" - If app is not installed
3741 None - on error
3742 """
Jon Hall146f1522015-03-24 15:33:24 -07003743 try:
3744 if not isinstance( appName, types.StringType ):
3745 main.log.error( self.name + ".appStatus(): appName must be" +
3746 " a string" )
3747 return None
3748 output = self.apps( jsonFormat=True )
3749 appsJson = json.loads( output )
3750 state = None
3751 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003752 if appName == app.get( 'name' ):
3753 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003754 break
3755 if state == "ACTIVE" or state == "INSTALLED":
3756 return state
3757 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003758 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003759 return "UNINSTALLED"
3760 elif state:
3761 main.log.error( "Unexpected state from 'onos:apps': " +
3762 str( state ) )
3763 return state
Jon Hallc6793552016-01-19 14:18:37 -08003764 except ( TypeError, ValueError ):
3765 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003766 return None
3767 except pexpect.EOF:
3768 main.log.error( self.name + ": EOF exception found" )
3769 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003770 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003771 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003772 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003773 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003774
Jon Hallbe379602015-03-24 13:39:32 -07003775 def app( self, appName, option ):
3776 """
3777 Interacts with the app command for ONOS. This command manages
3778 application inventory.
3779 """
Jon Hallbe379602015-03-24 13:39:32 -07003780 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003781 # Validate argument types
3782 valid = True
3783 if not isinstance( appName, types.StringType ):
3784 main.log.error( self.name + ".app(): appName must be a " +
3785 "string" )
3786 valid = False
3787 if not isinstance( option, types.StringType ):
3788 main.log.error( self.name + ".app(): option must be a string" )
3789 valid = False
3790 if not valid:
3791 return main.FALSE
3792 # Validate Option
3793 option = option.lower()
3794 # NOTE: Install may become a valid option
3795 if option == "activate":
3796 pass
3797 elif option == "deactivate":
3798 pass
3799 elif option == "uninstall":
3800 pass
3801 else:
3802 # Invalid option
3803 main.log.error( "The ONOS app command argument only takes " +
3804 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003805 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003806 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003807 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003808 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003809 assert output is not None, "Error in sendline"
3810 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003811 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003812 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003813 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003814 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003815 elif "No such application" in output:
3816 main.log.error( "The application '" + appName +
3817 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003818 return main.FALSE
3819 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003820 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003821 str( output ) )
3822 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003823 elif "Unsupported command:" in output:
3824 main.log.error( "Incorrect command given to 'app': " +
3825 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003826 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003827 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003828 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003829 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003830 except AssertionError:
3831 main.log.exception( self.name + ": AssertionError exception found" )
3832 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003833 except TypeError:
3834 main.log.exception( self.name + ": Object not as expected" )
3835 return main.ERROR
3836 except pexpect.EOF:
3837 main.log.error( self.name + ": EOF exception found" )
3838 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003839 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003840 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003841 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003842 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003843
Jon Hallbd16b922015-03-26 17:53:15 -07003844 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003845 """
3846 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003847 appName is the hierarchical app name, not the feature name
3848 If check is True, method will check the status of the app after the
3849 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003850 Returns main.TRUE if the command was successfully sent
3851 main.FALSE if the cli responded with an error or given
3852 incorrect input
3853 """
3854 try:
3855 if not isinstance( appName, types.StringType ):
3856 main.log.error( self.name + ".activateApp(): appName must be" +
3857 " a string" )
3858 return main.FALSE
3859 status = self.appStatus( appName )
3860 if status == "INSTALLED":
3861 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003862 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003863 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003864 status = self.appStatus( appName )
3865 if status == "ACTIVE":
3866 return main.TRUE
3867 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003868 main.log.debug( "The state of application " +
3869 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003870 time.sleep( 1 )
3871 return main.FALSE
3872 else: # not 'check' or command didn't succeed
3873 return response
Jon Hall146f1522015-03-24 15:33:24 -07003874 elif status == "ACTIVE":
3875 return main.TRUE
3876 elif status == "UNINSTALLED":
3877 main.log.error( self.name + ": Tried to activate the " +
3878 "application '" + appName + "' which is not " +
3879 "installed." )
3880 else:
3881 main.log.error( "Unexpected return value from appStatus: " +
3882 str( status ) )
3883 return main.ERROR
3884 except TypeError:
3885 main.log.exception( self.name + ": Object not as expected" )
3886 return main.ERROR
3887 except pexpect.EOF:
3888 main.log.error( self.name + ": EOF exception found" )
3889 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003890 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003891 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003892 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003893 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003894
Jon Hallbd16b922015-03-26 17:53:15 -07003895 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003896 """
3897 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003898 appName is the hierarchical app name, not the feature name
3899 If check is True, method will check the status of the app after the
3900 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003901 Returns main.TRUE if the command was successfully sent
3902 main.FALSE if the cli responded with an error or given
3903 incorrect input
3904 """
3905 try:
3906 if not isinstance( appName, types.StringType ):
3907 main.log.error( self.name + ".deactivateApp(): appName must " +
3908 "be a string" )
3909 return main.FALSE
3910 status = self.appStatus( appName )
3911 if status == "INSTALLED":
3912 return main.TRUE
3913 elif status == "ACTIVE":
3914 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003915 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003916 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003917 status = self.appStatus( appName )
3918 if status == "INSTALLED":
3919 return main.TRUE
3920 else:
3921 time.sleep( 1 )
3922 return main.FALSE
3923 else: # not check or command didn't succeed
3924 return response
Jon Hall146f1522015-03-24 15:33:24 -07003925 elif status == "UNINSTALLED":
3926 main.log.warn( self.name + ": Tried to deactivate the " +
3927 "application '" + appName + "' which is not " +
3928 "installed." )
3929 return main.TRUE
3930 else:
3931 main.log.error( "Unexpected return value from appStatus: " +
3932 str( status ) )
3933 return main.ERROR
3934 except TypeError:
3935 main.log.exception( self.name + ": Object not as expected" )
3936 return main.ERROR
3937 except pexpect.EOF:
3938 main.log.error( self.name + ": EOF exception found" )
3939 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003940 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003941 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003942 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003943 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003944
Jon Hallbd16b922015-03-26 17:53:15 -07003945 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003946 """
3947 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003948 appName is the hierarchical app name, not the feature name
3949 If check is True, method will check the status of the app after the
3950 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003951 Returns main.TRUE if the command was successfully sent
3952 main.FALSE if the cli responded with an error or given
3953 incorrect input
3954 """
3955 # TODO: check with Thomas about the state machine for apps
3956 try:
3957 if not isinstance( appName, types.StringType ):
3958 main.log.error( self.name + ".uninstallApp(): appName must " +
3959 "be a string" )
3960 return main.FALSE
3961 status = self.appStatus( appName )
3962 if status == "INSTALLED":
3963 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003964 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003965 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003966 status = self.appStatus( appName )
3967 if status == "UNINSTALLED":
3968 return main.TRUE
3969 else:
3970 time.sleep( 1 )
3971 return main.FALSE
3972 else: # not check or command didn't succeed
3973 return response
Jon Hall146f1522015-03-24 15:33:24 -07003974 elif status == "ACTIVE":
3975 main.log.warn( self.name + ": Tried to uninstall the " +
3976 "application '" + appName + "' which is " +
3977 "currently active." )
3978 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003979 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003980 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003981 status = self.appStatus( appName )
3982 if status == "UNINSTALLED":
3983 return main.TRUE
3984 else:
3985 time.sleep( 1 )
3986 return main.FALSE
3987 else: # not check or command didn't succeed
3988 return response
Jon Hall146f1522015-03-24 15:33:24 -07003989 elif status == "UNINSTALLED":
3990 return main.TRUE
3991 else:
3992 main.log.error( "Unexpected return value from appStatus: " +
3993 str( status ) )
3994 return main.ERROR
3995 except TypeError:
3996 main.log.exception( self.name + ": Object not as expected" )
3997 return main.ERROR
3998 except pexpect.EOF:
3999 main.log.error( self.name + ": EOF exception found" )
4000 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004001 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004002 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004003 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004004 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004005
4006 def appIDs( self, jsonFormat=True ):
4007 """
4008 Show the mappings between app id and app names given by the 'app-ids'
4009 cli command
4010 """
4011 try:
4012 cmdStr = "app-ids"
4013 if jsonFormat:
4014 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004015 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004016 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004017 assert "Command not found:" not in output, output
4018 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004019 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004020 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004021 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004022 return None
4023 except TypeError:
4024 main.log.exception( self.name + ": Object not as expected" )
4025 return None
4026 except pexpect.EOF:
4027 main.log.error( self.name + ": EOF exception found" )
4028 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004029 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004030 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004031 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004032 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004033
4034 def appToIDCheck( self ):
4035 """
4036 This method will check that each application's ID listed in 'apps' is
4037 the same as the ID listed in 'app-ids'. The check will also check that
4038 there are no duplicate IDs issued. Note that an app ID should be
4039 a globaly unique numerical identifier for app/app-like features. Once
4040 an ID is registered, the ID is never freed up so that if an app is
4041 reinstalled it will have the same ID.
4042
4043 Returns: main.TRUE if the check passes and
4044 main.FALSE if the check fails or
4045 main.ERROR if there is some error in processing the test
4046 """
4047 try:
Jon Hall0e240372018-05-02 11:21:57 -07004048 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004049 rawJson = self.appIDs( jsonFormat=True )
4050 if rawJson:
4051 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004052 else:
Jon Hall0e240372018-05-02 11:21:57 -07004053 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4054 return main.FALSE
4055
4056 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004057 rawJson = self.apps( jsonFormat=True )
4058 if rawJson:
4059 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004060 else:
Jon Hallc6793552016-01-19 14:18:37 -08004061 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004062 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004063
Jon Hallbd16b922015-03-26 17:53:15 -07004064 result = main.TRUE
4065 for app in apps:
4066 appID = app.get( 'id' )
4067 if appID is None:
4068 main.log.error( "Error parsing app: " + str( app ) )
4069 result = main.FALSE
4070 appName = app.get( 'name' )
4071 if appName is None:
4072 main.log.error( "Error parsing app: " + str( app ) )
4073 result = main.FALSE
4074 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004075 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004076 if not current: # if ids doesn't have this id
4077 result = main.FALSE
4078 main.log.error( "'app-ids' does not have the ID for " +
4079 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004080 main.log.debug( "apps command returned: " + str( app ) +
4081 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004082 elif len( current ) > 1:
4083 # there is more than one app with this ID
4084 result = main.FALSE
4085 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004086 elif not current[ 0 ][ 'name' ] == appName:
4087 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004088 result = main.FALSE
4089 main.log.error( "'app-ids' has " + str( currentName ) +
4090 " registered under id:" + str( appID ) +
4091 " but 'apps' has " + str( appName ) )
4092 else:
4093 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004094
Jon Hallbd16b922015-03-26 17:53:15 -07004095 # now make sure that app-ids has no duplicates
4096 idsList = []
4097 namesList = []
4098 for item in ids:
4099 idsList.append( item[ 'id' ] )
4100 namesList.append( item[ 'name' ] )
4101 if len( idsList ) != len( set( idsList ) ) or\
4102 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004103 main.log.error( "'app-ids' has some duplicate entries: \n"
4104 + json.dumps( ids,
4105 sort_keys=True,
4106 indent=4,
4107 separators=( ',', ': ' ) ) )
4108 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004109 return result
Jon Hallc6793552016-01-19 14:18:37 -08004110 except ( TypeError, ValueError ):
4111 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004112 return main.ERROR
4113 except pexpect.EOF:
4114 main.log.error( self.name + ": EOF exception found" )
4115 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004116 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004117 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004118 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004119 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004120
Jon Hallfb760a02015-04-13 15:35:03 -07004121 def getCfg( self, component=None, propName=None, short=False,
4122 jsonFormat=True ):
4123 """
4124 Get configuration settings from onos cli
4125 Optional arguments:
4126 component - Optionally only list configurations for a specific
4127 component. If None, all components with configurations
4128 are displayed. Case Sensitive string.
4129 propName - If component is specified, propName option will show
4130 only this specific configuration from that component.
4131 Case Sensitive string.
4132 jsonFormat - Returns output as json. Note that this will override
4133 the short option
4134 short - Short, less verbose, version of configurations.
4135 This is overridden by the json option
4136 returns:
4137 Output from cli as a string or None on error
4138 """
4139 try:
4140 baseStr = "cfg"
4141 cmdStr = " get"
4142 componentStr = ""
4143 if component:
4144 componentStr += " " + component
4145 if propName:
4146 componentStr += " " + propName
4147 if jsonFormat:
4148 baseStr += " -j"
4149 elif short:
4150 baseStr += " -s"
4151 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004152 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004153 assert "Command not found:" not in output, output
4154 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004155 return output
4156 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004157 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004158 return None
4159 except TypeError:
4160 main.log.exception( self.name + ": Object not as expected" )
4161 return None
4162 except pexpect.EOF:
4163 main.log.error( self.name + ": EOF exception found" )
4164 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004165 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004166 except Exception:
4167 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004168 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004169
4170 def setCfg( self, component, propName, value=None, check=True ):
4171 """
4172 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004173 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004174 component - The case sensitive name of the component whose
4175 property is to be set
4176 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004177 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004178 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004179 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004180 check - Boolean, Check whether the option was successfully set this
4181 only applies when a value is given.
4182 returns:
4183 main.TRUE on success or main.FALSE on failure. If check is False,
4184 will return main.TRUE unless there is an error
4185 """
4186 try:
4187 baseStr = "cfg"
4188 cmdStr = " set " + str( component ) + " " + str( propName )
4189 if value is not None:
4190 cmdStr += " " + str( value )
4191 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004192 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004193 assert "Command not found:" not in output, output
4194 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004195 if value and check:
4196 results = self.getCfg( component=str( component ),
4197 propName=str( propName ),
4198 jsonFormat=True )
4199 # Check if current value is what we just set
4200 try:
4201 jsonOutput = json.loads( results )
4202 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004203 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004204 main.log.exception( "Error parsing cfg output" )
4205 main.log.error( "output:" + repr( results ) )
4206 return main.FALSE
4207 if current == str( value ):
4208 return main.TRUE
4209 return main.FALSE
4210 return main.TRUE
4211 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004212 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004213 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004214 except ( TypeError, ValueError ):
4215 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004216 return main.FALSE
4217 except pexpect.EOF:
4218 main.log.error( self.name + ": EOF exception found" )
4219 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004220 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004221 except Exception:
4222 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004223 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004224
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004225 def distPrimitivesSend( self, cmd ):
4226 """
4227 Function to handle sending cli commands for the distributed primitives test app
4228
4229 This command will catch some exceptions and retry the command on some
4230 specific store exceptions.
4231
4232 Required arguments:
4233 cmd - The command to send to the cli
4234 returns:
4235 string containing the cli output
4236 None on Error
4237 """
4238 try:
4239 output = self.sendline( cmd )
4240 try:
4241 assert output is not None, "Error in sendline"
4242 # TODO: Maybe make this less hardcoded
4243 # ConsistentMap Exceptions
4244 assert "org.onosproject.store.service" not in output
4245 # Node not leader
4246 assert "java.lang.IllegalStateException" not in output
4247 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004248 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004249 "command: " + str( output ) )
4250 retryTime = 30 # Conservative time, given by Madan
4251 main.log.info( "Waiting " + str( retryTime ) +
4252 "seconds before retrying." )
4253 time.sleep( retryTime ) # Due to change in mastership
4254 output = self.sendline( cmd )
4255 assert output is not None, "Error in sendline"
4256 assert "Command not found:" not in output, output
4257 assert "Error executing command" not in output, output
4258 main.log.info( self.name + ": " + output )
4259 return output
4260 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004261 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004262 return None
4263 except TypeError:
4264 main.log.exception( self.name + ": Object not as expected" )
4265 return None
4266 except pexpect.EOF:
4267 main.log.error( self.name + ": EOF exception found" )
4268 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004269 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004270 except Exception:
4271 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004272 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004273
Jon Hall390696c2015-05-05 17:13:41 -07004274 def setTestAdd( self, setName, values ):
4275 """
4276 CLI command to add elements to a distributed set.
4277 Arguments:
4278 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004279 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004280 Example usages:
4281 setTestAdd( "set1", "a b c" )
4282 setTestAdd( "set2", "1" )
4283 returns:
4284 main.TRUE on success OR
4285 main.FALSE if elements were already in the set OR
4286 main.ERROR on error
4287 """
4288 try:
4289 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004290 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004291 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4292 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004293 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004294 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004295 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004296 return main.FALSE
4297 else:
4298 main.log.error( self.name + ": setTestAdd did not" +
4299 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004300 main.log.debug( self.name + " actual: " + repr( output ) )
4301 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004302 except TypeError:
4303 main.log.exception( self.name + ": Object not as expected" )
4304 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004305 except Exception:
4306 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004307 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004308
4309 def setTestRemove( self, setName, values, clear=False, retain=False ):
4310 """
4311 CLI command to remove elements from a distributed set.
4312 Required arguments:
4313 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004314 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004315 Optional arguments:
4316 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004317 retain - Retain only the given values. (intersection of the
4318 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004319 returns:
4320 main.TRUE on success OR
4321 main.FALSE if the set was not changed OR
4322 main.ERROR on error
4323 """
4324 try:
4325 cmdStr = "set-test-remove "
4326 if clear:
4327 cmdStr += "-c " + str( setName )
4328 elif retain:
4329 cmdStr += "-r " + str( setName ) + " " + str( values )
4330 else:
4331 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004332 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004333 if clear:
4334 pattern = "Set " + str( setName ) + " cleared"
4335 if re.search( pattern, output ):
4336 return main.TRUE
4337 elif retain:
4338 positivePattern = str( setName ) + " was pruned to contain " +\
4339 "only elements of set \[(.*)\]"
4340 negativePattern = str( setName ) + " was not changed by " +\
4341 "retaining only elements of the set " +\
4342 "\[(.*)\]"
4343 if re.search( positivePattern, output ):
4344 return main.TRUE
4345 elif re.search( negativePattern, output ):
4346 return main.FALSE
4347 else:
4348 positivePattern = "\[(.*)\] was removed from the set " +\
4349 str( setName )
4350 if ( len( values.split() ) == 1 ):
4351 negativePattern = "\[(.*)\] was not in set " +\
4352 str( setName )
4353 else:
4354 negativePattern = "No element of \[(.*)\] was in set " +\
4355 str( setName )
4356 if re.search( positivePattern, output ):
4357 return main.TRUE
4358 elif re.search( negativePattern, output ):
4359 return main.FALSE
4360 main.log.error( self.name + ": setTestRemove did not" +
4361 " match expected output" )
4362 main.log.debug( self.name + " expected: " + pattern )
4363 main.log.debug( self.name + " actual: " + repr( output ) )
4364 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004365 except TypeError:
4366 main.log.exception( self.name + ": Object not as expected" )
4367 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004368 except Exception:
4369 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004370 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004371
4372 def setTestGet( self, setName, values="" ):
4373 """
4374 CLI command to get the elements in a distributed set.
4375 Required arguments:
4376 setName - The name of the set to remove from.
4377 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004378 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004379 returns:
4380 main.ERROR on error OR
4381 A list of elements in the set if no optional arguments are
4382 supplied OR
4383 A tuple containing the list then:
4384 main.FALSE if the given values are not in the set OR
4385 main.TRUE if the given values are in the set OR
4386 """
4387 try:
4388 values = str( values ).strip()
4389 setName = str( setName ).strip()
4390 length = len( values.split() )
4391 containsCheck = None
4392 # Patterns to match
4393 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004394 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004395 containsTrue = "Set " + setName + " contains the value " + values
4396 containsFalse = "Set " + setName + " did not contain the value " +\
4397 values
4398 containsAllTrue = "Set " + setName + " contains the the subset " +\
4399 setPattern
4400 containsAllFalse = "Set " + setName + " did not contain the the" +\
4401 " subset " + setPattern
4402
4403 cmdStr = "set-test-get "
4404 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004405 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004406 if length == 0:
4407 match = re.search( pattern, output )
4408 else: # if given values
4409 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004410 patternTrue = pattern + "\r\n" + containsTrue
4411 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004412 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004413 patternTrue = pattern + "\r\n" + containsAllTrue
4414 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004415 matchTrue = re.search( patternTrue, output )
4416 matchFalse = re.search( patternFalse, output )
4417 if matchTrue:
4418 containsCheck = main.TRUE
4419 match = matchTrue
4420 elif matchFalse:
4421 containsCheck = main.FALSE
4422 match = matchFalse
4423 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004424 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004425 "expected output" )
4426 main.log.debug( self.name + " expected: " + pattern )
4427 main.log.debug( self.name + " actual: " + repr( output ) )
4428 match = None
4429 if match:
4430 setMatch = match.group( 1 )
4431 if setMatch == '':
4432 setList = []
4433 else:
4434 setList = setMatch.split( ", " )
4435 if length > 0:
4436 return ( setList, containsCheck )
4437 else:
4438 return setList
4439 else: # no match
4440 main.log.error( self.name + ": setTestGet did not" +
4441 " match expected output" )
4442 main.log.debug( self.name + " expected: " + pattern )
4443 main.log.debug( self.name + " actual: " + repr( output ) )
4444 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004445 except TypeError:
4446 main.log.exception( self.name + ": Object not as expected" )
4447 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004448 except Exception:
4449 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004450 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004451
4452 def setTestSize( self, setName ):
4453 """
4454 CLI command to get the elements in a distributed set.
4455 Required arguments:
4456 setName - The name of the set to remove from.
4457 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004458 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004459 None on error
4460 """
4461 try:
4462 # TODO: Should this check against the number of elements returned
4463 # and then return true/false based on that?
4464 setName = str( setName ).strip()
4465 # Patterns to match
4466 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004467 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004468 setPattern
4469 cmdStr = "set-test-get -s "
4470 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004471 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004472 if output:
4473 match = re.search( pattern, output )
4474 if match:
4475 setSize = int( match.group( 1 ) )
4476 setMatch = match.group( 2 )
4477 if len( setMatch.split() ) == setSize:
4478 main.log.info( "The size returned by " + self.name +
4479 " matches the number of elements in " +
4480 "the returned set" )
4481 else:
4482 main.log.error( "The size returned by " + self.name +
4483 " does not match the number of " +
4484 "elements in the returned set." )
4485 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004486 else: # no match
4487 main.log.error( self.name + ": setTestGet did not" +
4488 " match expected output" )
4489 main.log.debug( self.name + " expected: " + pattern )
4490 main.log.debug( self.name + " actual: " + repr( output ) )
4491 return None
Jon Hall390696c2015-05-05 17:13:41 -07004492 except TypeError:
4493 main.log.exception( self.name + ": Object not as expected" )
4494 return None
Jon Hall390696c2015-05-05 17:13:41 -07004495 except Exception:
4496 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004497 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004498
Jon Hall80daded2015-05-27 16:07:00 -07004499 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004500 """
4501 Command to list the various counters in the system.
4502 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004503 if jsonFormat, a string of the json object returned by the cli
4504 command
4505 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004506 None on error
4507 """
Jon Hall390696c2015-05-05 17:13:41 -07004508 try:
Jon Hall390696c2015-05-05 17:13:41 -07004509 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004510 if jsonFormat:
4511 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004512 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004513 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004514 assert "Command not found:" not in output, output
4515 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004516 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004517 return output
Jon Hall390696c2015-05-05 17:13:41 -07004518 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004519 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004520 return None
Jon Hall390696c2015-05-05 17:13:41 -07004521 except TypeError:
4522 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004523 return None
Jon Hall390696c2015-05-05 17:13:41 -07004524 except pexpect.EOF:
4525 main.log.error( self.name + ": EOF exception found" )
4526 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004527 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004528 except Exception:
4529 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004530 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004531
Jon Hall935db192016-04-19 00:22:04 -07004532 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004533 """
Jon Halle1a3b752015-07-22 13:02:46 -07004534 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004535 Required arguments:
4536 counter - The name of the counter to increment.
4537 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004538 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004539 returns:
4540 integer value of the counter or
4541 None on Error
4542 """
4543 try:
4544 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004545 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004546 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004547 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004548 if delta != 1:
4549 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004550 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004551 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004552 match = re.search( pattern, output )
4553 if match:
4554 return int( match.group( 1 ) )
4555 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004556 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004557 " match expected output." )
4558 main.log.debug( self.name + " expected: " + pattern )
4559 main.log.debug( self.name + " actual: " + repr( output ) )
4560 return None
Jon Hall390696c2015-05-05 17:13:41 -07004561 except TypeError:
4562 main.log.exception( self.name + ": Object not as expected" )
4563 return None
Jon Hall390696c2015-05-05 17:13:41 -07004564 except Exception:
4565 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004566 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004567
Jon Hall935db192016-04-19 00:22:04 -07004568 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004569 """
4570 CLI command to get a distributed counter then add a delta to it.
4571 Required arguments:
4572 counter - The name of the counter to increment.
4573 Optional arguments:
4574 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004575 returns:
4576 integer value of the counter or
4577 None on Error
4578 """
4579 try:
4580 counter = str( counter )
4581 delta = int( delta )
4582 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004583 cmdStr += counter
4584 if delta != 1:
4585 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004586 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004587 pattern = counter + " was updated to (-?\d+)"
4588 match = re.search( pattern, output )
4589 if match:
4590 return int( match.group( 1 ) )
4591 else:
4592 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4593 " match expected output." )
4594 main.log.debug( self.name + " expected: " + pattern )
4595 main.log.debug( self.name + " actual: " + repr( output ) )
4596 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004597 except TypeError:
4598 main.log.exception( self.name + ": Object not as expected" )
4599 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004600 except Exception:
4601 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004602 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004603
4604 def valueTestGet( self, valueName ):
4605 """
4606 CLI command to get the value of an atomic value.
4607 Required arguments:
4608 valueName - The name of the value to get.
4609 returns:
4610 string value of the value or
4611 None on Error
4612 """
4613 try:
4614 valueName = str( valueName )
4615 cmdStr = "value-test "
4616 operation = "get"
4617 cmdStr = "value-test {} {}".format( valueName,
4618 operation )
4619 output = self.distPrimitivesSend( cmdStr )
4620 pattern = "(\w+)"
4621 match = re.search( pattern, output )
4622 if match:
4623 return match.group( 1 )
4624 else:
4625 main.log.error( self.name + ": valueTestGet did not" +
4626 " match expected output." )
4627 main.log.debug( self.name + " expected: " + pattern )
4628 main.log.debug( self.name + " actual: " + repr( output ) )
4629 return None
4630 except TypeError:
4631 main.log.exception( self.name + ": Object not as expected" )
4632 return None
4633 except Exception:
4634 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004635 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004636
4637 def valueTestSet( self, valueName, newValue ):
4638 """
4639 CLI command to set the value of an atomic value.
4640 Required arguments:
4641 valueName - The name of the value to set.
4642 newValue - The value to assign to the given value.
4643 returns:
4644 main.TRUE on success or
4645 main.ERROR on Error
4646 """
4647 try:
4648 valueName = str( valueName )
4649 newValue = str( newValue )
4650 operation = "set"
4651 cmdStr = "value-test {} {} {}".format( valueName,
4652 operation,
4653 newValue )
4654 output = self.distPrimitivesSend( cmdStr )
4655 if output is not None:
4656 return main.TRUE
4657 else:
4658 return main.ERROR
4659 except TypeError:
4660 main.log.exception( self.name + ": Object not as expected" )
4661 return main.ERROR
4662 except Exception:
4663 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004664 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004665
4666 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4667 """
4668 CLI command to compareAndSet the value of an atomic value.
4669 Required arguments:
4670 valueName - The name of the value.
4671 oldValue - Compare the current value of the atomic value to this
4672 newValue - If the value equals oldValue, set the value to newValue
4673 returns:
4674 main.TRUE on success or
4675 main.FALSE on failure or
4676 main.ERROR on Error
4677 """
4678 try:
4679 valueName = str( valueName )
4680 oldValue = str( oldValue )
4681 newValue = str( newValue )
4682 operation = "compareAndSet"
4683 cmdStr = "value-test {} {} {} {}".format( valueName,
4684 operation,
4685 oldValue,
4686 newValue )
4687 output = self.distPrimitivesSend( cmdStr )
4688 pattern = "(\w+)"
4689 match = re.search( pattern, output )
4690 if match:
4691 result = match.group( 1 )
4692 if result == "true":
4693 return main.TRUE
4694 elif result == "false":
4695 return main.FALSE
4696 else:
4697 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4698 " match expected output." )
4699 main.log.debug( self.name + " expected: " + pattern )
4700 main.log.debug( self.name + " actual: " + repr( output ) )
4701 return main.ERROR
4702 except TypeError:
4703 main.log.exception( self.name + ": Object not as expected" )
4704 return main.ERROR
4705 except Exception:
4706 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004707 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004708
4709 def valueTestGetAndSet( self, valueName, newValue ):
4710 """
4711 CLI command to getAndSet the value of an atomic value.
4712 Required arguments:
4713 valueName - The name of the value to get.
4714 newValue - The value to assign to the given value
4715 returns:
4716 string value of the value or
4717 None on Error
4718 """
4719 try:
4720 valueName = str( valueName )
4721 cmdStr = "value-test "
4722 operation = "getAndSet"
4723 cmdStr += valueName + " " + operation
4724 cmdStr = "value-test {} {} {}".format( valueName,
4725 operation,
4726 newValue )
4727 output = self.distPrimitivesSend( cmdStr )
4728 pattern = "(\w+)"
4729 match = re.search( pattern, output )
4730 if match:
4731 return match.group( 1 )
4732 else:
4733 main.log.error( self.name + ": valueTestGetAndSet did not" +
4734 " match expected output." )
4735 main.log.debug( self.name + " expected: " + pattern )
4736 main.log.debug( self.name + " actual: " + repr( output ) )
4737 return None
4738 except TypeError:
4739 main.log.exception( self.name + ": Object not as expected" )
4740 return None
4741 except Exception:
4742 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004743 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004744
4745 def valueTestDestroy( self, valueName ):
4746 """
4747 CLI command to destroy an atomic value.
4748 Required arguments:
4749 valueName - The name of the value to destroy.
4750 returns:
4751 main.TRUE on success or
4752 main.ERROR on Error
4753 """
4754 try:
4755 valueName = str( valueName )
4756 cmdStr = "value-test "
4757 operation = "destroy"
4758 cmdStr += valueName + " " + operation
4759 output = self.distPrimitivesSend( cmdStr )
4760 if output is not None:
4761 return main.TRUE
4762 else:
4763 return main.ERROR
4764 except TypeError:
4765 main.log.exception( self.name + ": Object not as expected" )
4766 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004767 except Exception:
4768 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004769 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004770
YPZhangfebf7302016-05-24 16:45:56 -07004771 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004772 """
4773 Description: Execute summary command in onos
4774 Returns: json object ( summary -j ), returns main.FALSE if there is
4775 no output
4776
4777 """
4778 try:
4779 cmdStr = "summary"
4780 if jsonFormat:
4781 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004782 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004783 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004784 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004785 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004786 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004787 if not handle:
4788 main.log.error( self.name + ": There is no output in " +
4789 "summary command" )
4790 return main.FALSE
4791 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004792 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004793 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004794 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004795 except TypeError:
4796 main.log.exception( self.name + ": Object not as expected" )
4797 return None
4798 except pexpect.EOF:
4799 main.log.error( self.name + ": EOF exception found" )
4800 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004801 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004802 except Exception:
4803 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004804 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004805
Jon Hall935db192016-04-19 00:22:04 -07004806 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004807 """
4808 CLI command to get the value of a key in a consistent map using
4809 transactions. This a test function and can only get keys from the
4810 test map hard coded into the cli command
4811 Required arguments:
4812 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004813 returns:
4814 The string value of the key or
4815 None on Error
4816 """
4817 try:
4818 keyName = str( keyName )
4819 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004820 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004821 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004822 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4823 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004824 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004825 return None
4826 else:
4827 match = re.search( pattern, output )
4828 if match:
4829 return match.groupdict()[ 'value' ]
4830 else:
4831 main.log.error( self.name + ": transactionlMapGet did not" +
4832 " match expected output." )
4833 main.log.debug( self.name + " expected: " + pattern )
4834 main.log.debug( self.name + " actual: " + repr( output ) )
4835 return None
4836 except TypeError:
4837 main.log.exception( self.name + ": Object not as expected" )
4838 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004839 except Exception:
4840 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004841 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004842
Jon Hall935db192016-04-19 00:22:04 -07004843 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004844 """
4845 CLI command to put a value into 'numKeys' number of keys in a
4846 consistent map using transactions. This a test function and can only
4847 put into keys named 'Key#' of the test map hard coded into the cli command
4848 Required arguments:
4849 numKeys - Number of keys to add the value to
4850 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004851 returns:
4852 A dictionary whose keys are the name of the keys put into the map
4853 and the values of the keys are dictionaries whose key-values are
4854 'value': value put into map and optionaly
4855 'oldValue': Previous value in the key or
4856 None on Error
4857
4858 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004859 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4860 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004861 """
4862 try:
4863 numKeys = str( numKeys )
4864 value = str( value )
4865 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004866 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004867 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004868 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4869 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4870 results = {}
4871 for line in output.splitlines():
4872 new = re.search( newPattern, line )
4873 updated = re.search( updatedPattern, line )
4874 if new:
4875 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4876 elif updated:
4877 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004878 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004879 else:
4880 main.log.error( self.name + ": transactionlMapGet did not" +
4881 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004882 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4883 newPattern,
4884 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004885 main.log.debug( self.name + " actual: " + repr( output ) )
4886 return results
Jon Hall0e240372018-05-02 11:21:57 -07004887 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004888 main.log.exception( self.name + ": Object not as expected" )
4889 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004890 except Exception:
4891 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004892 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004893
acsmarsdaea66c2015-09-03 11:44:06 -07004894 def maps( self, jsonFormat=True ):
4895 """
4896 Description: Returns result of onos:maps
4897 Optional:
4898 * jsonFormat: enable json formatting of output
4899 """
4900 try:
4901 cmdStr = "maps"
4902 if jsonFormat:
4903 cmdStr += " -j"
4904 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004905 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004906 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004907 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004908 except AssertionError:
4909 main.log.exception( "" )
4910 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004911 except TypeError:
4912 main.log.exception( self.name + ": Object not as expected" )
4913 return None
4914 except pexpect.EOF:
4915 main.log.error( self.name + ": EOF exception found" )
4916 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004917 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004918 except Exception:
4919 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004920 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004921
4922 def getSwController( self, uri, jsonFormat=True ):
4923 """
4924 Descrition: Gets the controller information from the device
4925 """
4926 try:
4927 cmd = "device-controllers "
4928 if jsonFormat:
4929 cmd += "-j "
4930 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004931 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004932 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004933 return response
Jon Hallc6793552016-01-19 14:18:37 -08004934 except AssertionError:
4935 main.log.exception( "" )
4936 return None
GlennRC050596c2015-11-18 17:06:41 -08004937 except TypeError:
4938 main.log.exception( self.name + ": Object not as expected" )
4939 return None
4940 except pexpect.EOF:
4941 main.log.error( self.name + ": EOF exception found" )
4942 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004943 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004944 except Exception:
4945 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004946 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004947
4948 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4949 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004950 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004951
4952 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004953 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08004954 ip - String or List: The ip address of the controller.
4955 This parameter can be formed in a couple of different ways.
4956 VALID:
4957 10.0.0.1 - just the ip address
4958 tcp:10.0.0.1 - the protocol and the ip address
4959 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4960 so that you can add controllers with different
4961 protocols and ports
4962 INVALID:
4963 10.0.0.1:6653 - this is not supported by ONOS
4964
4965 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4966 port - The port number.
4967 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4968
4969 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4970 """
4971 try:
4972 cmd = "device-setcontrollers"
4973
4974 if jsonFormat:
4975 cmd += " -j"
4976 cmd += " " + uri
4977 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004978 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08004979 for item in ip:
4980 if ":" in item:
4981 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004982 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08004983 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004984 elif "." in sitem[ 1 ]:
4985 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08004986 else:
4987 main.log.error( "Malformed entry: " + item )
4988 raise TypeError
4989 else:
4990 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004991 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004992 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004993 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004994 if "Error" in response:
4995 main.log.error( response )
4996 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004997 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004998 except AssertionError:
4999 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005000 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005001 except TypeError:
5002 main.log.exception( self.name + ": Object not as expected" )
5003 return main.FALSE
5004 except pexpect.EOF:
5005 main.log.error( self.name + ": EOF exception found" )
5006 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005007 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005008 except Exception:
5009 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005010 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005011
5012 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005013 '''
GlennRC20fc6522015-12-23 23:26:57 -08005014 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005015 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005016 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005017 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005018 Returns:
5019 Returns main.FALSE if an exception is thrown or an error is present
5020 in the response. Otherwise, returns main.TRUE.
5021 NOTE:
5022 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005023 '''
GlennRC20fc6522015-12-23 23:26:57 -08005024 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005025 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005026 deviceStr = device
5027 device = []
5028 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005029
5030 for d in device:
5031 time.sleep( 1 )
5032 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005033 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005034 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005035 if "Error" in response:
5036 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5037 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005038 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005039 except AssertionError:
5040 main.log.exception( "" )
5041 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005042 except TypeError:
5043 main.log.exception( self.name + ": Object not as expected" )
5044 return main.FALSE
5045 except pexpect.EOF:
5046 main.log.error( self.name + ": EOF exception found" )
5047 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005048 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005049 except Exception:
5050 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005051 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005052
5053 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005054 '''
GlennRC20fc6522015-12-23 23:26:57 -08005055 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005056 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005057 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005058 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005059 Returns:
5060 Returns main.FALSE if an exception is thrown or an error is present
5061 in the response. Otherwise, returns main.TRUE.
5062 NOTE:
5063 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005064 '''
GlennRC20fc6522015-12-23 23:26:57 -08005065 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005066 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005067 host = list( host )
5068
5069 for h in host:
5070 time.sleep( 1 )
5071 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005072 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005073 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005074 if "Error" in response:
5075 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5076 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005077 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005078 except AssertionError:
5079 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005080 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005081 except TypeError:
5082 main.log.exception( self.name + ": Object not as expected" )
5083 return main.FALSE
5084 except pexpect.EOF:
5085 main.log.error( self.name + ": EOF exception found" )
5086 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005087 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005088 except Exception:
5089 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005090 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005091
YPZhangfebf7302016-05-24 16:45:56 -07005092 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005093 '''
GlennRCed771242016-01-13 17:02:47 -08005094 Description:
5095 Bring link down or up in the null-provider.
5096 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005097 begin - (string) One end of a device or switch.
5098 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005099 returns:
5100 main.TRUE if no exceptions were thrown and no Errors are
5101 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005102 '''
GlennRCed771242016-01-13 17:02:47 -08005103 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005104 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005105 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005106 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005107 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005108 if "Error" in response or "Failure" in response:
5109 main.log.error( response )
5110 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005111 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005112 except AssertionError:
5113 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005114 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005115 except TypeError:
5116 main.log.exception( self.name + ": Object not as expected" )
5117 return main.FALSE
5118 except pexpect.EOF:
5119 main.log.error( self.name + ": EOF exception found" )
5120 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005121 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005122 except Exception:
5123 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005124 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005125
Jon Hall2c8959e2016-12-16 12:17:34 -08005126 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005127 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005128 Description:
5129 Changes the state of port in an OF switch by means of the
5130 PORTSTATUS OF messages.
5131 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005132 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5133 port - (string) target port in the device. Ex: '2'
5134 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005135 returns:
5136 main.TRUE if no exceptions were thrown and no Errors are
5137 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005138 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005139 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005140 state = state.lower()
5141 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005142 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005143 response = self.sendline( cmd, showResponse=True )
5144 assert response is not None, "Error in sendline"
5145 assert "Command not found:" not in response, response
5146 if "Error" in response or "Failure" in response:
5147 main.log.error( response )
5148 return main.FALSE
5149 return main.TRUE
5150 except AssertionError:
5151 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005152 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005153 except TypeError:
5154 main.log.exception( self.name + ": Object not as expected" )
5155 return main.FALSE
5156 except pexpect.EOF:
5157 main.log.error( self.name + ": EOF exception found" )
5158 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005159 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005160 except Exception:
5161 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005162 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005163
5164 def logSet( self, level="INFO", app="org.onosproject" ):
5165 """
5166 Set the logging level to lvl for a specific app
5167 returns main.TRUE on success
5168 returns main.FALSE if Error occurred
5169 if noExit is True, TestON will not exit, but clean up
5170 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5171 Level defaults to INFO
5172 """
5173 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005174 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005175 self.handle.expect( "onos>" )
5176
5177 response = self.handle.before
5178 if re.search( "Error", response ):
5179 return main.FALSE
5180 return main.TRUE
5181 except pexpect.TIMEOUT:
5182 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005183 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005184 except pexpect.EOF:
5185 main.log.error( self.name + ": EOF exception found" )
5186 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005187 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005188 except Exception:
5189 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005190 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005191
5192 def getGraphDict( self, timeout=60, includeHost=False ):
5193 """
5194 Return a dictionary which describes the latest network topology data as a
5195 graph.
5196 An example of the dictionary:
5197 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5198 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5199 Each vertex should at least have an 'edges' attribute which describes the
5200 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005201 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005202 list of attributes.
5203 An example of the edges dictionary:
5204 'edges': { vertex2: { 'port': ..., 'weight': ... },
5205 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005206 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005207 in topology data.
5208 """
5209 graphDict = {}
5210 try:
5211 links = self.links()
5212 links = json.loads( links )
5213 devices = self.devices()
5214 devices = json.loads( devices )
5215 idToDevice = {}
5216 for device in devices:
5217 idToDevice[ device[ 'id' ] ] = device
5218 if includeHost:
5219 hosts = self.hosts()
5220 # FIXME: support 'includeHost' argument
5221 for link in links:
5222 nodeA = link[ 'src' ][ 'device' ]
5223 nodeB = link[ 'dst' ][ 'device' ]
5224 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005225 if nodeA not in graphDict.keys():
5226 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005227 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005228 'type': idToDevice[ nodeA ][ 'type' ],
5229 'available': idToDevice[ nodeA ][ 'available' ],
5230 'role': idToDevice[ nodeA ][ 'role' ],
5231 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5232 'hw': idToDevice[ nodeA ][ 'hw' ],
5233 'sw': idToDevice[ nodeA ][ 'sw' ],
5234 'serial': idToDevice[ nodeA ][ 'serial' ],
5235 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005236 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005237 else:
5238 # Assert nodeB is not connected to any current links of nodeA
You Wang9fc5ce42019-01-23 15:10:08 -08005239 # assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
5240 pass
Jon Halle0f0b342017-04-18 11:43:47 -07005241 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5242 'type': link[ 'type' ],
5243 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005244 return graphDict
5245 except ( TypeError, ValueError ):
5246 main.log.exception( self.name + ": Object not as expected" )
5247 return None
5248 except KeyError:
5249 main.log.exception( self.name + ": KeyError exception found" )
5250 return None
5251 except AssertionError:
5252 main.log.exception( self.name + ": AssertionError exception found" )
5253 return None
5254 except pexpect.EOF:
5255 main.log.error( self.name + ": EOF exception found" )
5256 main.log.error( self.name + ": " + self.handle.before )
5257 return None
5258 except Exception:
5259 main.log.exception( self.name + ": Uncaught exception!" )
5260 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005261
5262 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005263 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005264 Send command to check intent-perf summary
5265 Returns: dictionary for intent-perf summary
5266 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005267 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005268 cmd = "intent-perf -s"
5269 respDic = {}
5270 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005271 assert resp is not None, "Error in sendline"
5272 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005273 try:
5274 # Generate the dictionary to return
5275 for l in resp.split( "\n" ):
5276 # Delete any white space in line
5277 temp = re.sub( r'\s+', '', l )
5278 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005279 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005280
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005281 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005282 main.log.exception( self.name + ": Object not as expected" )
5283 return None
5284 except KeyError:
5285 main.log.exception( self.name + ": KeyError exception found" )
5286 return None
5287 except AssertionError:
5288 main.log.exception( self.name + ": AssertionError exception found" )
5289 return None
5290 except pexpect.EOF:
5291 main.log.error( self.name + ": EOF exception found" )
5292 main.log.error( self.name + ": " + self.handle.before )
5293 return None
5294 except Exception:
5295 main.log.exception( self.name + ": Uncaught exception!" )
5296 return None
5297 return respDic
5298
Chiyu Chengec63bde2016-11-17 18:11:36 -08005299 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005300 """
5301 Searches the latest ONOS log file for the given search term and
5302 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005303
chengchiyu08303a02016-09-08 17:40:26 -07005304 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005305 searchTerm:
5306 The string to grep from the ONOS log.
5307 startLine:
5308 The term that decides which line is the start to search the searchTerm in
5309 the karaf log. For now, startTerm only works in 'first' mode.
5310 logNum:
5311 In some extreme cases, one karaf log is not big enough to contain all the
5312 information.Because of this, search mutiply logs is necessary to capture
5313 the right result. logNum is the number of karaf logs that we need to search
5314 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005315 mode:
5316 all: return all the strings that contain the search term
5317 last: return the last string that contains the search term
5318 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005319 num: return the number of times that the searchTerm appears in the log
5320 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005321 """
5322 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005323 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005324 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005325 logPath = '/opt/onos/log/karaf.log.'
5326 logPaths = '/opt/onos/log/karaf.log'
5327 for i in range( 1, logNum ):
5328 logPaths = logPath + str( i ) + " " + logPaths
5329 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005330 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005331 # 100000000 is just a extreme large number to make sure this function can
5332 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005333 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005334 if mode == 'all':
5335 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005336 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005337 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005338 elif mode == 'first':
5339 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5340 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005341 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005342 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005343 return num
You Wang6d301d42017-04-21 10:49:33 -07005344 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005345 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005346 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005347 else:
5348 main.log.error( self.name + " unsupported mode" )
5349 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005350 before = self.sendline( cmd )
5351 before = before.splitlines()
5352 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005353 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005354 return returnLines
5355 except AssertionError:
5356 main.log.error( self.name + " searchTerm is not string type" )
5357 return None
5358 except pexpect.EOF:
5359 main.log.error( self.name + ": EOF exception found" )
5360 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005361 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005362 except pexpect.TIMEOUT:
5363 main.log.error( self.name + ": TIMEOUT exception found" )
5364 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005365 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005366 except Exception:
5367 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005368 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005369
5370 def vplsShow( self, jsonFormat=True ):
5371 """
5372 Description: Returns result of onos:vpls show, which should list the
5373 configured VPLS networks and the assigned interfaces.
5374 Optional:
5375 * jsonFormat: enable json formatting of output
5376 Returns:
5377 The output of the command or None on error.
5378 """
5379 try:
5380 cmdStr = "vpls show"
5381 if jsonFormat:
5382 raise NotImplementedError
5383 cmdStr += " -j"
5384 handle = self.sendline( cmdStr )
5385 assert handle is not None, "Error in sendline"
5386 assert "Command not found:" not in handle, handle
5387 return handle
5388 except AssertionError:
5389 main.log.exception( "" )
5390 return None
5391 except TypeError:
5392 main.log.exception( self.name + ": Object not as expected" )
5393 return None
5394 except pexpect.EOF:
5395 main.log.error( self.name + ": EOF exception found" )
5396 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005397 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005398 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005399 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005400 return None
5401 except Exception:
5402 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005403 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005404
5405 def parseVplsShow( self ):
5406 """
5407 Parse the cli output of 'vpls show' into json output. This is required
5408 as there is currently no json output available.
5409 """
5410 try:
5411 output = []
5412 raw = self.vplsShow( jsonFormat=False )
5413 namePat = "VPLS name: (?P<name>\w+)"
5414 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5415 encapPat = "Encapsulation: (?P<encap>\w+)"
5416 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5417 mIter = re.finditer( pattern, raw )
5418 for match in mIter:
5419 item = {}
5420 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005421 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005422 if ifaces == [ "" ]:
5423 ifaces = []
5424 item[ 'interfaces' ] = ifaces
5425 encap = match.group( 'encap' )
5426 if encap != 'NONE':
5427 item[ 'encapsulation' ] = encap.lower()
5428 output.append( item )
5429 return output
5430 except Exception:
5431 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005432 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005433
5434 def vplsList( self, jsonFormat=True ):
5435 """
5436 Description: Returns result of onos:vpls list, which should list the
5437 configured VPLS networks.
5438 Optional:
5439 * jsonFormat: enable json formatting of output
5440 """
5441 try:
5442 cmdStr = "vpls list"
5443 if jsonFormat:
5444 raise NotImplementedError
5445 cmdStr += " -j"
5446 handle = self.sendline( cmdStr )
5447 assert handle is not None, "Error in sendline"
5448 assert "Command not found:" not in handle, handle
5449 return handle
5450 except AssertionError:
5451 main.log.exception( "" )
5452 return None
5453 except TypeError:
5454 main.log.exception( self.name + ": Object not as expected" )
5455 return None
5456 except pexpect.EOF:
5457 main.log.error( self.name + ": EOF exception found" )
5458 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005459 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005460 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005461 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005462 return None
5463 except Exception:
5464 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005465 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005466
5467 def vplsCreate( self, network ):
5468 """
5469 CLI command to create a new VPLS network.
5470 Required arguments:
5471 network - String name of the network to create.
5472 returns:
5473 main.TRUE on success and main.FALSE on failure
5474 """
5475 try:
5476 network = str( network )
5477 cmdStr = "vpls create "
5478 cmdStr += network
5479 output = self.sendline( cmdStr )
5480 assert output is not None, "Error in sendline"
5481 assert "Command not found:" not in output, output
5482 assert "Error executing command" not in output, output
5483 assert "VPLS already exists:" not in output, output
5484 return main.TRUE
5485 except AssertionError:
5486 main.log.exception( "" )
5487 return main.FALSE
5488 except TypeError:
5489 main.log.exception( self.name + ": Object not as expected" )
5490 return main.FALSE
5491 except pexpect.EOF:
5492 main.log.error( self.name + ": EOF exception found" )
5493 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005494 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005495 except Exception:
5496 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005497 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005498
5499 def vplsDelete( self, network ):
5500 """
5501 CLI command to delete a VPLS network.
5502 Required arguments:
5503 network - Name of the network to delete.
5504 returns:
5505 main.TRUE on success and main.FALSE on failure
5506 """
5507 try:
5508 network = str( network )
5509 cmdStr = "vpls delete "
5510 cmdStr += network
5511 output = self.sendline( cmdStr )
5512 assert output is not None, "Error in sendline"
5513 assert "Command not found:" not in output, output
5514 assert "Error executing command" not in output, output
5515 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005516 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005517 return main.TRUE
5518 except AssertionError:
5519 main.log.exception( "" )
5520 return main.FALSE
5521 except TypeError:
5522 main.log.exception( self.name + ": Object not as expected" )
5523 return main.FALSE
5524 except pexpect.EOF:
5525 main.log.error( self.name + ": EOF exception found" )
5526 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005527 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005528 except Exception:
5529 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005530 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005531
5532 def vplsAddIface( self, network, iface ):
5533 """
5534 CLI command to add an interface to a VPLS network.
5535 Required arguments:
5536 network - Name of the network to add the interface to.
5537 iface - The ONOS name for an interface.
5538 returns:
5539 main.TRUE on success and main.FALSE on failure
5540 """
5541 try:
5542 network = str( network )
5543 iface = str( iface )
5544 cmdStr = "vpls add-if "
5545 cmdStr += network + " " + iface
5546 output = self.sendline( cmdStr )
5547 assert output is not None, "Error in sendline"
5548 assert "Command not found:" not in output, output
5549 assert "Error executing command" not in output, output
5550 assert "already associated to network" not in output, output
5551 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005552 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005553 return main.TRUE
5554 except AssertionError:
5555 main.log.exception( "" )
5556 return main.FALSE
5557 except TypeError:
5558 main.log.exception( self.name + ": Object not as expected" )
5559 return main.FALSE
5560 except pexpect.EOF:
5561 main.log.error( self.name + ": EOF exception found" )
5562 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005563 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005564 except Exception:
5565 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005566 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005567
5568 def vplsRemIface( self, network, iface ):
5569 """
5570 CLI command to remove an interface from a VPLS network.
5571 Required arguments:
5572 network - Name of the network to remove the interface from.
5573 iface - Name of the interface to remove.
5574 returns:
5575 main.TRUE on success and main.FALSE on failure
5576 """
5577 try:
5578 iface = str( iface )
5579 cmdStr = "vpls rem-if "
5580 cmdStr += network + " " + iface
5581 output = self.sendline( cmdStr )
5582 assert output is not None, "Error in sendline"
5583 assert "Command not found:" not in output, output
5584 assert "Error executing command" not in output, output
5585 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005586 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005587 return main.TRUE
5588 except AssertionError:
5589 main.log.exception( "" )
5590 return main.FALSE
5591 except TypeError:
5592 main.log.exception( self.name + ": Object not as expected" )
5593 return main.FALSE
5594 except pexpect.EOF:
5595 main.log.error( self.name + ": EOF exception found" )
5596 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005597 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005598 except Exception:
5599 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005600 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005601
5602 def vplsClean( self ):
5603 """
5604 Description: Clears the VPLS app configuration.
5605 Returns: main.TRUE on success and main.FALSE on failure
5606 """
5607 try:
5608 cmdStr = "vpls clean"
5609 handle = self.sendline( cmdStr )
5610 assert handle is not None, "Error in sendline"
5611 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005612 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005613 return handle
5614 except AssertionError:
5615 main.log.exception( "" )
5616 return main.FALSE
5617 except TypeError:
5618 main.log.exception( self.name + ": Object not as expected" )
5619 return main.FALSE
5620 except pexpect.EOF:
5621 main.log.error( self.name + ": EOF exception found" )
5622 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005623 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005624 except Exception:
5625 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005626 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005627
5628 def vplsSetEncap( self, network, encapType ):
5629 """
5630 CLI command to add an interface to a VPLS network.
5631 Required arguments:
5632 network - Name of the network to create.
5633 encapType - Type of encapsulation.
5634 returns:
5635 main.TRUE on success and main.FALSE on failure
5636 """
5637 try:
5638 network = str( network )
5639 encapType = str( encapType ).upper()
5640 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5641 cmdStr = "vpls set-encap "
5642 cmdStr += network + " " + encapType
5643 output = self.sendline( cmdStr )
5644 assert output is not None, "Error in sendline"
5645 assert "Command not found:" not in output, output
5646 assert "Error executing command" not in output, output
5647 assert "already associated to network" not in output, output
5648 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005649 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005650 return main.TRUE
5651 except AssertionError:
5652 main.log.exception( "" )
5653 return main.FALSE
5654 except TypeError:
5655 main.log.exception( self.name + ": Object not as expected" )
5656 return main.FALSE
5657 except pexpect.EOF:
5658 main.log.error( self.name + ": EOF exception found" )
5659 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005660 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005661 except Exception:
5662 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005663 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005664
5665 def interfaces( self, jsonFormat=True ):
5666 """
5667 Description: Returns result of interfaces command.
5668 Optional:
5669 * jsonFormat: enable json formatting of output
5670 Returns:
5671 The output of the command or None on error.
5672 """
5673 try:
5674 cmdStr = "interfaces"
5675 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005676 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005677 cmdStr += " -j"
5678 handle = self.sendline( cmdStr )
5679 assert handle is not None, "Error in sendline"
5680 assert "Command not found:" not in handle, handle
5681 return handle
5682 except AssertionError:
5683 main.log.exception( "" )
5684 return None
5685 except TypeError:
5686 main.log.exception( self.name + ": Object not as expected" )
5687 return None
5688 except pexpect.EOF:
5689 main.log.error( self.name + ": EOF exception found" )
5690 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005691 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005692 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005693 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005694 return None
5695 except Exception:
5696 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005697 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005698
5699 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005700 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005701 Get the timestamp of searchTerm from karaf log.
5702
5703 Arguments:
5704 splitTerm_before and splitTerm_after:
5705
5706 The terms that split the string that contains the timeStamp of
5707 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5708 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5709 and the splitTerm_after is "x"
5710
5711 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005712 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005713 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005714 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005715 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005716 return main.ERROR
5717 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005718 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005719 main.log.warn( "Captured timestamp string is empty" )
5720 return main.ERROR
5721 lines = lines[ 0 ]
5722 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005723 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005724 # get the target value
5725 line = lines.split( splitTerm_before )
5726 key = line[ 1 ].split( splitTerm_after )
5727 return int( key[ 0 ] )
5728 except IndexError:
5729 main.log.warn( "Index Error!" )
5730 return main.ERROR
5731 except AssertionError:
5732 main.log.warn( "Search Term Not Found " )
5733 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005734
5735 def workQueueAdd( self, queueName, value ):
5736 """
5737 CLI command to add a string to the specified Work Queue.
5738 This function uses the distributed primitives test app, which
5739 gives some cli access to distributed primitives for testing
5740 purposes only.
5741
5742 Required arguments:
5743 queueName - The name of the queue to add to
5744 value - The value to add to the queue
5745 returns:
5746 main.TRUE on success, main.FALSE on failure and
5747 main.ERROR on error.
5748 """
5749 try:
5750 queueName = str( queueName )
5751 value = str( value )
5752 prefix = "work-queue-test"
5753 operation = "add"
5754 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5755 output = self.distPrimitivesSend( cmdStr )
5756 if "Invalid operation name" in output:
5757 main.log.warn( output )
5758 return main.ERROR
5759 elif "Done" in output:
5760 return main.TRUE
5761 except TypeError:
5762 main.log.exception( self.name + ": Object not as expected" )
5763 return main.ERROR
5764 except Exception:
5765 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005766 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005767
5768 def workQueueAddMultiple( self, queueName, value1, value2 ):
5769 """
5770 CLI command to add two strings to the specified Work Queue.
5771 This function uses the distributed primitives test app, which
5772 gives some cli access to distributed primitives for testing
5773 purposes only.
5774
5775 Required arguments:
5776 queueName - The name of the queue to add to
5777 value1 - The first value to add to the queue
5778 value2 - The second value to add to the queue
5779 returns:
5780 main.TRUE on success, main.FALSE on failure and
5781 main.ERROR on error.
5782 """
5783 try:
5784 queueName = str( queueName )
5785 value1 = str( value1 )
5786 value2 = str( value2 )
5787 prefix = "work-queue-test"
5788 operation = "addMultiple"
5789 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5790 output = self.distPrimitivesSend( cmdStr )
5791 if "Invalid operation name" in output:
5792 main.log.warn( output )
5793 return main.ERROR
5794 elif "Done" in output:
5795 return main.TRUE
5796 except TypeError:
5797 main.log.exception( self.name + ": Object not as expected" )
5798 return main.ERROR
5799 except Exception:
5800 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005801 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005802
5803 def workQueueTakeAndComplete( self, queueName, number=1 ):
5804 """
5805 CLI command to take a value from the specified Work Queue and compelte it.
5806 This function uses the distributed primitives test app, which
5807 gives some cli access to distributed primitives for testing
5808 purposes only.
5809
5810 Required arguments:
5811 queueName - The name of the queue to add to
5812 number - The number of items to take and complete
5813 returns:
5814 main.TRUE on success, main.FALSE on failure and
5815 main.ERROR on error.
5816 """
5817 try:
5818 queueName = str( queueName )
5819 number = str( int( number ) )
5820 prefix = "work-queue-test"
5821 operation = "takeAndComplete"
5822 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5823 output = self.distPrimitivesSend( cmdStr )
5824 if "Invalid operation name" in output:
5825 main.log.warn( output )
5826 return main.ERROR
5827 elif "Done" in output:
5828 return main.TRUE
5829 except TypeError:
5830 main.log.exception( self.name + ": Object not as expected" )
5831 return main.ERROR
5832 except Exception:
5833 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005834 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005835
5836 def workQueueDestroy( self, queueName ):
5837 """
5838 CLI command to destroy the specified Work Queue.
5839 This function uses the distributed primitives test app, which
5840 gives some cli access to distributed primitives for testing
5841 purposes only.
5842
5843 Required arguments:
5844 queueName - The name of the queue to add to
5845 returns:
5846 main.TRUE on success, main.FALSE on failure and
5847 main.ERROR on error.
5848 """
5849 try:
5850 queueName = str( queueName )
5851 prefix = "work-queue-test"
5852 operation = "destroy"
5853 cmdStr = " ".join( [ prefix, queueName, operation ] )
5854 output = self.distPrimitivesSend( cmdStr )
5855 if "Invalid operation name" in output:
5856 main.log.warn( output )
5857 return main.ERROR
5858 return main.TRUE
5859 except TypeError:
5860 main.log.exception( self.name + ": Object not as expected" )
5861 return main.ERROR
5862 except Exception:
5863 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005864 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005865
5866 def workQueueTotalPending( self, queueName ):
5867 """
5868 CLI command to get the Total Pending items of the specified Work Queue.
5869 This function uses the distributed primitives test app, which
5870 gives some cli access to distributed primitives for testing
5871 purposes only.
5872
5873 Required arguments:
5874 queueName - The name of the queue to add to
5875 returns:
5876 The number of Pending items in the specified work queue or
5877 None on error
5878 """
5879 try:
5880 queueName = str( queueName )
5881 prefix = "work-queue-test"
5882 operation = "totalPending"
5883 cmdStr = " ".join( [ prefix, queueName, operation ] )
5884 output = self.distPrimitivesSend( cmdStr )
5885 pattern = r'\d+'
5886 if "Invalid operation name" in output:
5887 main.log.warn( output )
5888 return None
5889 else:
5890 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005891 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005892 except ( AttributeError, TypeError ):
5893 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5894 return None
5895 except Exception:
5896 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005897 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005898
5899 def workQueueTotalCompleted( self, queueName ):
5900 """
5901 CLI command to get the Total Completed items of the specified Work Queue.
5902 This function uses the distributed primitives test app, which
5903 gives some cli access to distributed primitives for testing
5904 purposes only.
5905
5906 Required arguments:
5907 queueName - The name of the queue to add to
5908 returns:
5909 The number of complete items in the specified work queue or
5910 None on error
5911 """
5912 try:
5913 queueName = str( queueName )
5914 prefix = "work-queue-test"
5915 operation = "totalCompleted"
5916 cmdStr = " ".join( [ prefix, queueName, operation ] )
5917 output = self.distPrimitivesSend( cmdStr )
5918 pattern = r'\d+'
5919 if "Invalid operation name" in output:
5920 main.log.warn( output )
5921 return None
5922 else:
5923 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005924 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005925 except ( AttributeError, TypeError ):
5926 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5927 return None
5928 except Exception:
5929 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005930 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005931
5932 def workQueueTotalInProgress( self, queueName ):
5933 """
5934 CLI command to get the Total In Progress items of the specified Work Queue.
5935 This function uses the distributed primitives test app, which
5936 gives some cli access to distributed primitives for testing
5937 purposes only.
5938
5939 Required arguments:
5940 queueName - The name of the queue to add to
5941 returns:
5942 The number of In Progress items in the specified work queue or
5943 None on error
5944 """
5945 try:
5946 queueName = str( queueName )
5947 prefix = "work-queue-test"
5948 operation = "totalInProgress"
5949 cmdStr = " ".join( [ prefix, queueName, operation ] )
5950 output = self.distPrimitivesSend( cmdStr )
5951 pattern = r'\d+'
5952 if "Invalid operation name" in output:
5953 main.log.warn( output )
5954 return None
5955 else:
5956 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005957 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005958 except ( AttributeError, TypeError ):
5959 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5960 return None
5961 except Exception:
5962 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005963 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005964
5965 def events( self, args='-a' ):
5966 """
5967 Description: Returns events -a command output
5968 Optional:
5969 add other arguments
5970 """
5971 try:
5972 cmdStr = "events"
5973 if args:
5974 cmdStr += " " + args
5975 handle = self.sendline( cmdStr )
5976 assert handle is not None, "Error in sendline"
5977 assert "Command not found:" not in handle, handle
5978 return handle
5979 except AssertionError:
5980 main.log.exception( "" )
5981 return None
5982 except TypeError:
5983 main.log.exception( self.name + ": Object not as expected" )
5984 return None
5985 except pexpect.EOF:
5986 main.log.error( self.name + ": EOF exception found" )
5987 main.log.error( self.name + ": " + self.handle.before )
5988 main.cleanAndExit()
5989 except Exception:
5990 main.log.exception( self.name + ": Uncaught exception!" )
5991 main.cleanAndExit()
5992
5993 def getMaster( self, deviceID ):
5994 """
5995 Description: Obtains current master using "roles" command for a specific deviceID
5996 """
5997 try:
5998 return str( self.getRole( deviceID )[ 'master' ] )
5999 except AssertionError:
6000 main.log.exception( "" )
6001 return None
6002 except TypeError:
6003 main.log.exception( self.name + ": Object not as expected" )
6004 return None
6005 except pexpect.EOF:
6006 main.log.error( self.name + ": EOF exception found" )
6007 main.log.error( self.name + ": " + self.handle.before )
6008 main.cleanAndExit()
6009 except Exception:
6010 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006011 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006012
6013 def issu( self ):
6014 """
6015 Short summary of In-Service Software Upgrade status
6016
6017 Returns the output of the cli command or None on Error
6018 """
6019 try:
6020 cmdStr = "issu"
6021 handle = self.sendline( cmdStr )
6022 assert handle is not None, "Error in sendline"
6023 assert "Command not found:" not in handle, handle
6024 assert "Unsupported command:" not in handle, handle
6025 return handle
6026 except AssertionError:
6027 main.log.exception( "" )
6028 return None
6029 except TypeError:
6030 main.log.exception( self.name + ": Object not as expected" )
6031 return None
6032 except pexpect.EOF:
6033 main.log.error( self.name + ": EOF exception found" )
6034 main.log.error( self.name + ": " + self.handle.before )
6035 main.cleanAndExit()
6036 except Exception:
6037 main.log.exception( self.name + ": Uncaught exception!" )
6038 main.cleanAndExit()
6039
6040 def issuInit( self ):
6041 """
6042 Initiates an In-Service Software Upgrade
6043
6044 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6045 """
6046 try:
6047 cmdStr = "issu init"
6048 handle = self.sendline( cmdStr )
6049 assert handle is not None, "Error in sendline"
6050 assert "Command not found:" not in handle, handle
6051 assert "Unsupported command:" not in handle, handle
6052 if "Initialized" in handle:
6053 return main.TRUE
6054 else:
6055 return main.FALSE
6056 except AssertionError:
6057 main.log.exception( "" )
6058 return main.ERROR
6059 except TypeError:
6060 main.log.exception( self.name + ": Object not as expected" )
6061 return main.ERROR
6062 except pexpect.EOF:
6063 main.log.error( self.name + ": EOF exception found" )
6064 main.log.error( self.name + ": " + self.handle.before )
6065 main.cleanAndExit()
6066 except Exception:
6067 main.log.exception( self.name + ": Uncaught exception!" )
6068 main.cleanAndExit()
6069
6070 def issuUpgrade( self ):
6071 """
6072 Transitions stores to upgraded nodes
6073
6074 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6075 """
6076 try:
6077 cmdStr = "issu upgrade"
6078 handle = self.sendline( cmdStr )
6079 assert handle is not None, "Error in sendline"
6080 assert "Command not found:" not in handle, handle
6081 assert "Unsupported command:" not in handle, handle
6082 if "Upgraded" in handle:
6083 return main.TRUE
6084 else:
6085 return main.FALSE
6086 except AssertionError:
6087 main.log.exception( "" )
6088 return main.ERROR
6089 except TypeError:
6090 main.log.exception( self.name + ": Object not as expected" )
6091 return main.ERROR
6092 except pexpect.EOF:
6093 main.log.error( self.name + ": EOF exception found" )
6094 main.log.error( self.name + ": " + self.handle.before )
6095 main.cleanAndExit()
6096 except Exception:
6097 main.log.exception( self.name + ": Uncaught exception!" )
6098 main.cleanAndExit()
6099
6100 def issuCommit( self ):
6101 """
6102 Finalizes an In-Service Software Upgrade
6103
6104 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6105 """
6106 try:
6107 cmdStr = "issu commit"
6108 handle = self.sendline( cmdStr )
6109 assert handle is not None, "Error in sendline"
6110 assert "Command not found:" not in handle, handle
6111 assert "Unsupported command:" not in handle, handle
6112 # TODO: Check the version returned by this command
6113 if "Committed version" in handle:
6114 return main.TRUE
6115 else:
6116 return main.FALSE
6117 except AssertionError:
6118 main.log.exception( "" )
6119 return main.ERROR
6120 except TypeError:
6121 main.log.exception( self.name + ": Object not as expected" )
6122 return main.ERROR
6123 except pexpect.EOF:
6124 main.log.error( self.name + ": EOF exception found" )
6125 main.log.error( self.name + ": " + self.handle.before )
6126 main.cleanAndExit()
6127 except Exception:
6128 main.log.exception( self.name + ": Uncaught exception!" )
6129 main.cleanAndExit()
6130
6131 def issuRollback( self ):
6132 """
6133 Rolls back an In-Service Software Upgrade
6134
6135 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6136 """
6137 try:
6138 cmdStr = "issu rollback"
6139 handle = self.sendline( cmdStr )
6140 assert handle is not None, "Error in sendline"
6141 assert "Command not found:" not in handle, handle
6142 assert "Unsupported command:" not in handle, handle
6143 # TODO: Check the version returned by this command
6144 if "Rolled back to version" in handle:
6145 return main.TRUE
6146 else:
6147 return main.FALSE
6148 except AssertionError:
6149 main.log.exception( "" )
6150 return main.ERROR
6151 except TypeError:
6152 main.log.exception( self.name + ": Object not as expected" )
6153 return main.ERROR
6154 except pexpect.EOF:
6155 main.log.error( self.name + ": EOF exception found" )
6156 main.log.error( self.name + ": " + self.handle.before )
6157 main.cleanAndExit()
6158 except Exception:
6159 main.log.exception( self.name + ": Uncaught exception!" )
6160 main.cleanAndExit()
6161
6162 def issuReset( self ):
6163 """
6164 Resets the In-Service Software Upgrade status after a rollback
6165
6166 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6167 """
6168 try:
6169 cmdStr = "issu reset"
6170 handle = self.sendline( cmdStr )
6171 assert handle is not None, "Error in sendline"
6172 assert "Command not found:" not in handle, handle
6173 assert "Unsupported command:" not in handle, handle
6174 # TODO: Check the version returned by this command
6175 if "Reset version" in handle:
6176 return main.TRUE
6177 else:
6178 return main.FALSE
6179 except AssertionError:
6180 main.log.exception( "" )
6181 return main.ERROR
6182 except TypeError:
6183 main.log.exception( self.name + ": Object not as expected" )
6184 return main.ERROR
6185 except pexpect.EOF:
6186 main.log.error( self.name + ": EOF exception found" )
6187 main.log.error( self.name + ": " + self.handle.before )
6188 main.cleanAndExit()
6189 except Exception:
6190 main.log.exception( self.name + ": Uncaught exception!" )
6191 main.cleanAndExit()
6192
6193 def issuStatus( self ):
6194 """
6195 Status of an In-Service Software Upgrade
6196
6197 Returns the output of the cli command or None on Error
6198 """
6199 try:
6200 cmdStr = "issu status"
6201 handle = self.sendline( cmdStr )
6202 assert handle is not None, "Error in sendline"
6203 assert "Command not found:" not in handle, handle
6204 assert "Unsupported command:" not in handle, handle
6205 return handle
6206 except AssertionError:
6207 main.log.exception( "" )
6208 return None
6209 except TypeError:
6210 main.log.exception( self.name + ": Object not as expected" )
6211 return None
6212 except pexpect.EOF:
6213 main.log.error( self.name + ": EOF exception found" )
6214 main.log.error( self.name + ": " + self.handle.before )
6215 main.cleanAndExit()
6216 except Exception:
6217 main.log.exception( self.name + ": Uncaught exception!" )
6218 main.cleanAndExit()
6219
6220 def issuVersion( self ):
6221 """
6222 Get the version of an In-Service Software Upgrade
6223
6224 Returns the output of the cli command or None on Error
6225 """
6226 try:
6227 cmdStr = "issu version"
6228 handle = self.sendline( cmdStr )
6229 assert handle is not None, "Error in sendline"
6230 assert "Command not found:" not in handle, handle
6231 assert "Unsupported command:" not in handle, handle
6232 return handle
6233 except AssertionError:
6234 main.log.exception( "" )
6235 return None
6236 except TypeError:
6237 main.log.exception( self.name + ": Object not as expected" )
6238 return None
6239 except pexpect.EOF:
6240 main.log.error( self.name + ": EOF exception found" )
6241 main.log.error( self.name + ": " + self.handle.before )
6242 main.cleanAndExit()
6243 except Exception:
6244 main.log.exception( self.name + ": Uncaught exception!" )
6245 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006246
6247 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6248 """
6249 Create a multicast route by calling 'mcast-join' command
6250 sIP: source IP of the multicast route
6251 groupIP: group IP of the multicast route
6252 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6253 dPorts: a list of destination ports of the multicast route
6254 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6255 """
6256 try:
6257 cmdStr = "mcast-join"
6258 cmdStr += " " + str( sIP )
6259 cmdStr += " " + str( groupIP )
6260 cmdStr += " " + str( sPort )
6261 assert isinstance( dPorts, list )
6262 for dPort in dPorts:
6263 cmdStr += " " + str( dPort )
6264 handle = self.sendline( cmdStr )
6265 assert handle is not None, "Error in sendline"
6266 assert "Command not found:" not in handle, handle
6267 assert "Unsupported command:" not in handle, handle
6268 assert "Error executing command" not in handle, handle
6269 if "Added the mcast route" in handle:
6270 return main.TRUE
6271 else:
6272 return main.FALSE
6273 except AssertionError:
6274 main.log.exception( "" )
6275 return None
6276 except TypeError:
6277 main.log.exception( self.name + ": Object not as expected" )
6278 return None
6279 except pexpect.EOF:
6280 main.log.error( self.name + ": EOF exception found" )
6281 main.log.error( self.name + ": " + self.handle.before )
6282 main.cleanAndExit()
6283 except Exception:
6284 main.log.exception( self.name + ": Uncaught exception!" )
6285 main.cleanAndExit()
6286
6287 def mcastDelete( self, sIP, groupIP, dPorts ):
6288 """
6289 Delete a multicast route by calling 'mcast-delete' command
6290 sIP: source IP of the multicast route
6291 groupIP: group IP of the multicast route
6292 dPorts: a list of destination ports of the multicast route
6293 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6294 """
6295 try:
6296 cmdStr = "mcast-delete"
6297 cmdStr += " " + str( sIP )
6298 cmdStr += " " + str( groupIP )
6299 assert isinstance( dPorts, list )
6300 for dPort in dPorts:
6301 cmdStr += " " + str( dPort )
6302 handle = self.sendline( cmdStr )
6303 assert handle is not None, "Error in sendline"
6304 assert "Command not found:" not in handle, handle
6305 assert "Unsupported command:" not in handle, handle
6306 assert "Error executing command" not in handle, handle
6307 if "Updated the mcast route" in handle:
6308 return main.TRUE
6309 else:
6310 return main.FALSE
6311 except AssertionError:
6312 main.log.exception( "" )
6313 return None
6314 except TypeError:
6315 main.log.exception( self.name + ": Object not as expected" )
6316 return None
6317 except pexpect.EOF:
6318 main.log.error( self.name + ": EOF exception found" )
6319 main.log.error( self.name + ": " + self.handle.before )
6320 main.cleanAndExit()
6321 except Exception:
6322 main.log.exception( self.name + ": Uncaught exception!" )
6323 main.cleanAndExit()
6324
6325 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6326 """
6327 Create a multicast route by calling 'mcast-host-join' command
6328 sAddr: we can provide * for ASM or a specific address for SSM
6329 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006330 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006331 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6332 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6333 """
6334 try:
6335 cmdStr = "mcast-host-join"
6336 cmdStr += " -sAddr " + str( sAddr )
6337 cmdStr += " -gAddr " + str( gAddr )
6338 assert isinstance( srcs, list )
6339 for src in srcs:
6340 cmdStr += " -srcs " + str( src )
6341 assert isinstance( sinks, list )
6342 for sink in sinks:
6343 cmdStr += " -sinks " + str( sink )
6344 handle = self.sendline( cmdStr )
6345 assert handle is not None, "Error in sendline"
6346 assert "Command not found:" not in handle, handle
6347 assert "Unsupported command:" not in handle, handle
6348 assert "Error executing command" not in handle, handle
6349 if "Added the mcast route" in handle:
6350 return main.TRUE
6351 else:
6352 return main.FALSE
6353 except AssertionError:
6354 main.log.exception( "" )
6355 return None
6356 except TypeError:
6357 main.log.exception( self.name + ": Object not as expected" )
6358 return None
6359 except pexpect.EOF:
6360 main.log.error( self.name + ": EOF exception found" )
6361 main.log.error( self.name + ": " + self.handle.before )
6362 main.cleanAndExit()
6363 except Exception:
6364 main.log.exception( self.name + ": Uncaught exception!" )
6365 main.cleanAndExit()
6366
6367 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6368 """
6369 Delete multicast sink(s) by calling 'mcast-host-delete' command
6370 sAddr: we can provide * for ASM or a specific address for SSM
6371 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006372 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006373 will delete the route if not specified
6374 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6375 """
6376 try:
6377 cmdStr = "mcast-host-delete"
6378 cmdStr += " -sAddr " + str( sAddr )
6379 cmdStr += " -gAddr " + str( gAddr )
6380 if host:
6381 cmdStr += " -h " + str( host )
6382 handle = self.sendline( cmdStr )
6383 assert handle is not None, "Error in sendline"
6384 assert "Command not found:" not in handle, handle
6385 assert "Unsupported command:" not in handle, handle
6386 assert "Error executing command" not in handle, handle
6387 if "Updated the mcast route" in handle:
6388 return main.TRUE
6389 elif "Deleted the mcast route" in handle:
6390 return main.TRUE
6391 else:
6392 return main.FALSE
6393 except AssertionError:
6394 main.log.exception( "" )
6395 return None
6396 except TypeError:
6397 main.log.exception( self.name + ": Object not as expected" )
6398 return None
6399 except pexpect.EOF:
6400 main.log.error( self.name + ": EOF exception found" )
6401 main.log.error( self.name + ": " + self.handle.before )
6402 main.cleanAndExit()
6403 except Exception:
6404 main.log.exception( self.name + ": Uncaught exception!" )
6405 main.cleanAndExit()
6406
You Wang547893e2018-05-08 13:34:59 -07006407 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6408 """
6409 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6410 sAddr: we can provide * for ASM or a specific address for SSM
6411 gAddr: specifies multicast group address
6412 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6413 will delete the route if not specified
6414 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6415 """
6416 try:
6417 cmdStr = "mcast-sink-delete"
6418 cmdStr += " -sAddr " + str( sAddr )
6419 cmdStr += " -gAddr " + str( gAddr )
6420 if sink:
6421 cmdStr += " -s " + str( sink )
6422 handle = self.sendline( cmdStr )
6423 assert handle is not None, "Error in sendline"
6424 assert "Command not found:" not in handle, handle
6425 assert "Unsupported command:" not in handle, handle
6426 assert "Error executing command" not in handle, handle
6427 if "Updated the mcast route" in handle:
6428 return main.TRUE
6429 elif "Deleted the mcast route" in handle:
6430 return main.TRUE
6431 else:
6432 return main.FALSE
6433 except AssertionError:
6434 main.log.exception( "" )
6435 return None
6436 except TypeError:
6437 main.log.exception( self.name + ": Object not as expected" )
6438 return None
6439 except pexpect.EOF:
6440 main.log.error( self.name + ": EOF exception found" )
6441 main.log.error( self.name + ": " + self.handle.before )
6442 main.cleanAndExit()
6443 except Exception:
6444 main.log.exception( self.name + ": Uncaught exception!" )
6445 main.cleanAndExit()
6446
You Wange24d6272018-03-27 21:18:50 -07006447 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6448 """
6449 Delete multicast src(s) by calling 'mcast-source-delete' command
6450 sAddr: we can provide * for ASM or a specific address for SSM
6451 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006452 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 -07006453 will delete the route if not specified
6454 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6455 """
6456 try:
6457 cmdStr = "mcast-source-delete"
6458 cmdStr += " -sAddr " + str( sAddr )
6459 cmdStr += " -gAddr " + str( gAddr )
6460 if srcs:
6461 assert isinstance( srcs, list )
6462 for src in srcs:
6463 cmdStr += " -src " + str( src )
6464 handle = self.sendline( cmdStr )
6465 assert handle is not None, "Error in sendline"
6466 assert "Command not found:" not in handle, handle
6467 assert "Unsupported command:" not in handle, handle
6468 assert "Error executing command" not in handle, handle
6469 if "Updated the mcast route" in handle:
6470 return main.TRUE
6471 elif "Deleted the mcast route" in handle:
6472 return main.TRUE
6473 else:
6474 return main.FALSE
6475 except AssertionError:
6476 main.log.exception( "" )
6477 return None
6478 except TypeError:
6479 main.log.exception( self.name + ": Object not as expected" )
6480 return None
6481 except pexpect.EOF:
6482 main.log.error( self.name + ": EOF exception found" )
6483 main.log.error( self.name + ": " + self.handle.before )
6484 main.cleanAndExit()
6485 except Exception:
6486 main.log.exception( self.name + ": Uncaught exception!" )
6487 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006488
6489 def netcfg( self, jsonFormat=True, args="" ):
6490 """
6491 Run netcfg cli command with given args
6492 """
6493 try:
6494 cmdStr = "netcfg"
6495 if jsonFormat:
6496 cmdStr = cmdStr + " -j"
6497 if args:
6498 cmdStr = cmdStr + " " + str( args )
6499 handle = self.sendline( cmdStr )
6500 assert handle is not None, "Error in sendline"
6501 assert "Command not found:" not in handle, handle
6502 assert "Unsupported command:" not in handle, handle
6503 assert "Error executing command" not in handle, handle
6504 return handle
6505 except AssertionError:
6506 main.log.exception( "" )
6507 return None
6508 except TypeError:
6509 main.log.exception( self.name + ": Object not as expected" )
6510 return None
6511 except pexpect.EOF:
6512 main.log.error( self.name + ": EOF exception found" )
6513 main.log.error( self.name + ": " + self.handle.before )
6514 main.cleanAndExit()
6515 except Exception:
6516 main.log.exception( self.name + ": Uncaught exception!" )
6517 main.cleanAndExit()
6518
You Wang0fa76e72018-05-18 11:33:25 -07006519 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006520 """
You Wang54b1d672018-06-11 16:44:13 -07006521 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006522 Options:
6523 sAddr: IP address of the source host
6524 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006525 ipv6: True if hosts are IPv6
6526 verbose: return verbose t3 output if True
6527 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006528 """
6529 try:
6530 # Collect information of both hosts from onos
6531 hosts = self.hosts()
6532 hosts = json.loads( hosts )
6533 sHost = None
6534 dHost = None
6535 for host in hosts:
6536 if sAddr in host[ "ipAddresses" ]:
6537 sHost = host
6538 elif dAddr in host[ "ipAddresses" ]:
6539 dHost = host
6540 if sHost and dHost:
6541 break
6542 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006543 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006544 if simple:
6545 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006546 cmdStr = "t3-troubleshoot-simple"
6547 if verbose:
6548 cmdStr += " -vv"
6549 if ipv6:
6550 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006551 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006552 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006553 else:
You Wang54b1d672018-06-11 16:44:13 -07006554 for location in sHost[ "locations" ]:
6555 cmdStr = "t3-troubleshoot"
6556 if verbose:
6557 cmdStr += " -vv"
6558 if ipv6:
6559 cmdStr += " -et ipv6"
6560 cmdStr += " -s " + str( sAddr )
6561 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6562 cmdStr += " -sm " + str( sHost[ "mac" ] )
6563 if sHost[ "vlan" ] != "None":
6564 cmdStr += " -vid " + sHost[ "vlan" ]
6565 cmdStr += " -d " + str( dAddr )
6566 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6567 netcfg = json.loads( netcfg )
6568 assert netcfg, "Failed to get netcfg"
6569 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6570 cmdList.append( cmdStr )
6571 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006572 except AssertionError:
6573 main.log.exception( "" )
6574 return None
6575 except ( KeyError, TypeError ):
6576 main.log.exception( self.name + ": Object not as expected" )
6577 return None
6578 except Exception:
6579 main.log.exception( self.name + ": Uncaught exception!" )
6580 main.cleanAndExit()
6581
6582 def t3( self, sAddr, dAddr, ipv6=False ):
6583 """
You Wang54b1d672018-06-11 16:44:13 -07006584 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006585 Options:
6586 sAddr: IP address of the source host
6587 dAddr: IP address of the destination host
6588 """
6589 try:
You Wang54b1d672018-06-11 16:44:13 -07006590 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6591 assert cmdList is not None, "composeT3Command returned None"
6592 t3Output = ""
6593 for cmdStr in cmdList:
6594 handle = self.sendline( cmdStr )
6595 assert handle is not None, "Error in sendline"
6596 assert "Command not found:" not in handle, handle
6597 assert "Unsupported command:" not in handle, handle
6598 assert "Error executing command" not in handle, handle
6599 assert "Tracing packet" in handle
6600 t3Output += handle
6601 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006602 except AssertionError:
6603 main.log.exception( "" )
6604 return None
6605 except pexpect.EOF:
6606 main.log.error( self.name + ": EOF exception found" )
6607 main.log.error( self.name + ": " + self.handle.before )
6608 main.cleanAndExit()
6609 except Exception:
6610 main.log.exception( self.name + ": Uncaught exception!" )
6611 main.cleanAndExit()