blob: 76cc4159473f8b62ee9aa1a1f57c22a139179927 [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07004OCT 13 2014
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005Copyright 2014 Open Networking Foundation (ONF)
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07006
7Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
8the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
9or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
10
11 TestON is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 2 of the License, or
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000014 (at your option) any later version.
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070015
16 TestON is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with TestON. If not, see <http://www.gnu.org/licenses/>.
23"""
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000024
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070025"""
andrewonlab95ce8322014-10-13 14:12:04 -040026This driver enters the onos> prompt to issue commands.
27
kelvin8ec71442015-01-15 16:57:00 -080028Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -040029functions and document properly.
30
31If you are a contributor to the driver, please
32list your email here for future contact:
33
34jhall@onlab.us
35andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040036shreya@onlab.us
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +000037jeremyr@opennetworking.org
kelvin8ec71442015-01-15 16:57:00 -080038"""
andrewonlab95ce8322014-10-13 14:12:04 -040039import pexpect
40import re
Jon Hall30b82fa2015-03-04 17:15:43 -080041import json
42import types
Jon Hallbd16b922015-03-26 17:53:15 -070043import time
kelvin-onlaba4074292015-07-09 15:19:49 -070044import os
andrewonlab95ce8322014-10-13 14:12:04 -040045from drivers.common.clidriver import CLI
You Wangdb8cd0a2016-05-26 15:19:45 -070046from core.graph import Graph
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -070047from cStringIO import StringIO
48from itertools import izip
andrewonlab95ce8322014-10-13 14:12:04 -040049
kelvin8ec71442015-01-15 16:57:00 -080050class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040051
kelvin8ec71442015-01-15 16:57:00 -080052 def __init__( self ):
53 """
54 Initialize client
55 """
Jon Hallefbd9792015-03-05 16:11:36 -080056 self.name = None
57 self.home = None
58 self.handle = None
Devin Limdc78e202017-06-09 18:30:07 -070059 self.karafUser = None
60 self.karafPass = None
You Wangdb8cd0a2016-05-26 15:19:45 -070061 self.graph = Graph()
Devin Limdc78e202017-06-09 18:30:07 -070062 super( OnosCliDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080063
Jeremy Ronquillo82705492017-10-18 14:19:55 -070064 def checkOptions( self, var, defaultVar ):
Devin Limdc78e202017-06-09 18:30:07 -070065 if var is None or var == "":
66 return defaultVar
67 return var
Jeremy Ronquillo82705492017-10-18 14:19:55 -070068
kelvin8ec71442015-01-15 16:57:00 -080069 def connect( self, **connectargs ):
70 """
andrewonlab95ce8322014-10-13 14:12:04 -040071 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080072 """
andrewonlab95ce8322014-10-13 14:12:04 -040073 try:
74 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080075 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070076 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040077 for key in self.options:
78 if key == "home":
Devin Limdc78e202017-06-09 18:30:07 -070079 self.home = self.options[ key ]
80 elif key == "karaf_username":
81 self.karafUser = self.options[ key ]
82 elif key == "karaf_password":
83 self.karafPass = self.options[ key ]
84
Jeremy Ronquillo82705492017-10-18 14:19:55 -070085 self.home = self.checkOptions( self.home, "~/onos" )
86 self.karafUser = self.checkOptions( self.karafUser, self.user_name )
87 self.karafPass = self.checkOptions( self.karafPass, self.pwd )
andrewonlab95ce8322014-10-13 14:12:04 -040088
kelvin-onlaba4074292015-07-09 15:19:49 -070089 for key in self.options:
90 if key == 'onosIp':
91 self.onosIp = self.options[ 'onosIp' ]
92 break
93
kelvin8ec71442015-01-15 16:57:00 -080094 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070095
96 try:
Jon Hallc6793552016-01-19 14:18:37 -080097 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070098 self.ip_address = os.getenv( str( self.ip_address ) )
99 else:
100 main.log.info( self.name +
101 ": Trying to connect to " +
102 self.ip_address )
103
104 except KeyError:
105 main.log.info( "Invalid host name," +
106 " connecting to local host instead" )
107 self.ip_address = 'localhost'
108 except Exception as inst:
109 main.log.error( "Uncaught exception: " + str( inst ) )
110
kelvin8ec71442015-01-15 16:57:00 -0800111 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800112 user_name=self.user_name,
113 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800114 port=self.port,
115 pwd=self.pwd,
116 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400117
kelvin8ec71442015-01-15 16:57:00 -0800118 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700119 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400120 if self.handle:
121 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800122 else:
123 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400124 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800125 except TypeError:
126 main.log.exception( self.name + ": Object not as expected" )
127 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400128 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800129 main.log.error( self.name + ": EOF exception found" )
130 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700131 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800132 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800133 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700134 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400135
kelvin8ec71442015-01-15 16:57:00 -0800136 def disconnect( self ):
137 """
andrewonlab95ce8322014-10-13 14:12:04 -0400138 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800139 """
Jon Halld61331b2015-02-17 16:35:47 -0800140 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400141 try:
Jon Hall61282e32015-03-19 11:34:11 -0700142 if self.handle:
143 i = self.logout()
144 if i == main.TRUE:
145 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700146 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700147 self.handle.sendline( "exit" )
148 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800149 except TypeError:
150 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800151 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400152 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800153 main.log.error( self.name + ": EOF exception found" )
154 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700155 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700156 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700157 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800158 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800159 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400160 response = main.FALSE
161 return response
162
kelvin8ec71442015-01-15 16:57:00 -0800163 def logout( self ):
164 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500165 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700166 Returns main.TRUE if exited CLI and
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000167 main.FALSE on timeout (not guranteed you are disconnected)
Jon Hall61282e32015-03-19 11:34:11 -0700168 None on TypeError
169 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800170 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500171 try:
Jon Hall61282e32015-03-19 11:34:11 -0700172 if self.handle:
173 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700174 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ],
Jon Hall61282e32015-03-19 11:34:11 -0700175 timeout=10 )
176 if i == 0: # In ONOS CLI
177 self.handle.sendline( "logout" )
Devin Limdc78e202017-06-09 18:30:07 -0700178 j = self.handle.expect( [ self.prompt,
Jon Hallbfe00002016-04-05 10:23:54 -0700179 "Command not found:",
180 pexpect.TIMEOUT ] )
181 if j == 0: # Successfully logged out
182 return main.TRUE
183 elif j == 1 or j == 2:
184 # ONOS didn't fully load, and logout command isn't working
185 # or the command timed out
186 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700187 try:
Devin Limdc78e202017-06-09 18:30:07 -0700188 self.handle.expect( self.prompt )
Jon Hall64ab3bd2016-05-13 11:29:44 -0700189 except pexpect.TIMEOUT:
190 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700191 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700192 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700193 main.log.warn( "Unknown repsonse to logout command: '{}'",
194 repr( self.handle.before ) )
195 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700196 elif i == 1: # not in CLI
197 return main.TRUE
198 elif i == 3: # Timeout
199 return main.FALSE
200 else:
andrewonlab9627f432014-11-14 12:45:10 -0500201 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800202 except TypeError:
203 main.log.exception( self.name + ": Object not as expected" )
204 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500205 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800206 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700207 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700208 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700209 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700210 main.log.error( self.name +
211 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800212 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800213 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700214 main.cleanAndExit()
andrewonlab38d2b4a2014-11-13 16:28:47 -0500215
kelvin-onlabd3b64892015-01-20 13:26:24 -0800216 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800217 """
andrewonlab95ce8322014-10-13 14:12:04 -0400218 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800219
andrewonlab95ce8322014-10-13 14:12:04 -0400220 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800221 """
andrewonlab95ce8322014-10-13 14:12:04 -0400222 try:
223 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800224 main.log.error( "Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700225 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400226 else:
kelvin8ec71442015-01-15 16:57:00 -0800227 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800229 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400230 # and that this driver will have to change accordingly
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700231 self.handle.expect( str( cellname ) )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800232 handleBefore = self.handle.before
233 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800234 # Get the rest of the handle
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700235 self.handle.sendline( "" )
236 self.handle.expect( self.prompt )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800237 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400238
kelvin-onlabd3b64892015-01-20 13:26:24 -0800239 main.log.info( "Cell call returned: " + handleBefore +
240 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400241
242 return main.TRUE
243
Jon Halld4d4b372015-01-28 16:02:41 -0800244 except TypeError:
245 main.log.exception( self.name + ": Object not as expected" )
246 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400247 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800248 main.log.error( self.name + ": eof exception found" )
249 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700250 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800251 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800252 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700253 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -0800254
pingping-lin57a56ce2015-05-20 16:43:48 -0700255 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800256 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800257 """
Jon Hallefbd9792015-03-05 16:11:36 -0800258 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800259 by user would be used to set the current karaf shell idle timeout.
260 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800261 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800262 Below is an example to start a session with 60 seconds idle timeout
263 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800264
Hari Krishna25d42f72015-01-05 15:08:28 -0800265 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800266 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800267
kelvin-onlabd3b64892015-01-20 13:26:24 -0800268 Note: karafTimeout is left as str so that this could be read
269 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800270 """
You Wangf69ab392016-01-26 16:34:38 -0800271 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400272 try:
Jon Hall67253832016-12-05 09:47:13 -0800273 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800274 self.handle.sendline( "" )
275 x = self.handle.expect( [
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700276 self.prompt, "onos>" ], commandlineTimeout )
andrewonlab48829f62014-11-17 13:49:01 -0500277 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800278 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500279 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400280
Jon Hall67253832016-12-05 09:47:13 -0800281 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800282 if waitForStart:
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800283 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
284 startCliCommand = "onos-wait-for-start "
Chiyu Chengef109502016-11-21 15:51:38 -0800285 else:
286 startCliCommand = "onos "
287 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800288 i = self.handle.expect( [
289 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700290 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400291
292 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800293 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800294 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800295 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800296 "config:property-set -p org.apache.karaf.shell\
297 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800298 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700299 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800300 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800301 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400302 return main.TRUE
303 else:
kelvin8ec71442015-01-15 16:57:00 -0800304 # If failed, send ctrl+c to process and try again
305 main.log.info( "Starting CLI failed. Retrying..." )
306 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800307 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800308 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
309 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400310 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800311 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800312 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800313 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800314 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800315 "config:property-set -p org.apache.karaf.shell\
316 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800317 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700318 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800319 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800320 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400321 return main.TRUE
322 else:
kelvin8ec71442015-01-15 16:57:00 -0800323 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800324 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400325 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400326
Jon Halld4d4b372015-01-28 16:02:41 -0800327 except TypeError:
328 main.log.exception( self.name + ": Object not as expected" )
329 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400330 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800331 main.log.error( self.name + ": EOF exception found" )
332 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700333 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800334 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800335 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700336 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400337
suibin zhang116647a2016-05-06 16:30:09 -0700338 def startCellCli( self, karafTimeout="",
339 commandlineTimeout=10, onosStartTimeout=60 ):
340 """
341 Start CLI on onos ecll handle.
342
343 karafTimeout is an optional argument. karafTimeout value passed
344 by user would be used to set the current karaf shell idle timeout.
345 Note that when ever this property is modified the shell will exit and
346 the subsequent login would reflect new idle timeout.
347 Below is an example to start a session with 60 seconds idle timeout
348 ( input value is in milliseconds ):
349
350 tValue = "60000"
351
352 Note: karafTimeout is left as str so that this could be read
353 and passed to startOnosCli from PARAMS file as str.
354 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000355
suibin zhang116647a2016-05-06 16:30:09 -0700356 try:
357 self.handle.sendline( "" )
358 x = self.handle.expect( [
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700359 self.prompt, "onos>" ], commandlineTimeout )
suibin zhang116647a2016-05-06 16:30:09 -0700360
361 if x == 1:
362 main.log.info( "ONOS cli is already running" )
363 return main.TRUE
364
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800365 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
suibin zhang116647a2016-05-06 16:30:09 -0700366 self.handle.sendline( "/opt/onos/bin/onos" )
367 i = self.handle.expect( [
368 "onos>",
369 pexpect.TIMEOUT ], onosStartTimeout )
370
371 if i == 0:
372 main.log.info( self.name + " CLI Started successfully" )
373 if karafTimeout:
374 self.handle.sendline(
375 "config:property-set -p org.apache.karaf.shell\
376 sshIdleTimeout " +
377 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700378 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700379 self.handle.sendline( "/opt/onos/bin/onos" )
380 self.handle.expect( "onos>" )
381 return main.TRUE
382 else:
383 # If failed, send ctrl+c to process and try again
384 main.log.info( "Starting CLI failed. Retrying..." )
385 self.handle.send( "\x03" )
386 self.handle.sendline( "/opt/onos/bin/onos" )
387 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
388 timeout=30 )
389 if i == 0:
390 main.log.info( self.name + " CLI Started " +
391 "successfully after retry attempt" )
392 if karafTimeout:
393 self.handle.sendline(
394 "config:property-set -p org.apache.karaf.shell\
395 sshIdleTimeout " +
396 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700397 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700398 self.handle.sendline( "/opt/onos/bin/onos" )
399 self.handle.expect( "onos>" )
400 return main.TRUE
401 else:
402 main.log.error( "Connection to CLI " +
403 self.name + " timeout" )
404 return main.FALSE
405
406 except TypeError:
407 main.log.exception( self.name + ": Object not as expected" )
408 return None
409 except pexpect.EOF:
410 main.log.error( self.name + ": EOF exception found" )
411 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700412 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700413 except Exception:
414 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700415 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700416
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800417 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800418 """
419 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800420 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800421 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700422 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800423 Available level: DEBUG, TRACE, INFO, WARN, ERROR
424 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800425 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800426 """
427 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800428 lvlStr = ""
429 if level:
430 lvlStr = "--level=" + level
431
kelvin-onlab338f5512015-02-06 10:53:16 -0800432 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700433 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800434 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800435
kelvin-onlab9f541032015-02-04 16:19:53 -0800436 response = self.handle.before
437 if re.search( "Error", response ):
438 return main.FALSE
439 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700440 except pexpect.TIMEOUT:
441 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700442 if noExit:
443 main.cleanup()
444 return None
445 else:
Devin Lim44075962017-08-11 10:56:37 -0700446 main.cleanAndExit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800447 except pexpect.EOF:
448 main.log.error( self.name + ": EOF exception found" )
449 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700450 if noExit:
451 main.cleanup()
452 return None
453 else:
Devin Lim44075962017-08-11 10:56:37 -0700454 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800455 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800456 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700457 if noExit:
458 main.cleanup()
459 return None
460 else:
Devin Lim44075962017-08-11 10:56:37 -0700461 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400462
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700463 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, dollarSign=False ):
kelvin8ec71442015-01-15 16:57:00 -0800464 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800465 Send a completely user specified string to
466 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400467 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800468
YPZhang14a4aa92016-07-15 13:37:15 -0700469 if noExit is True, TestON will not exit, and return None
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700470 if dollarSign is True, TestON will not expect for '$' as a new CLI or onos> prompt
471 since '$' can be in the output.
YPZhangebf9eb52016-05-12 15:20:24 -0700472
andrewonlaba18f6bf2014-10-13 19:31:54 -0400473 Warning: There are no sanity checking to commands
474 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800475
kelvin8ec71442015-01-15 16:57:00 -0800476 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400477 try:
Jon Halla495f562016-05-16 18:03:26 -0700478 # Try to reconnect if disconnected from cli
479 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700480 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ] )
Jon Halla495f562016-05-16 18:03:26 -0700481 if i == 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700482 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700483 if self.onosIp:
484 main.log.warn( "Trying to reconnect " + self.onosIp )
485 reconnectResult = self.startOnosCli( self.onosIp )
486 if reconnectResult:
487 main.log.info( self.name + ": onos cli session reconnected." )
488 else:
489 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700490 if noExit:
491 return None
492 else:
Devin Lim44075962017-08-11 10:56:37 -0700493 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700494 else:
Devin Lim44075962017-08-11 10:56:37 -0700495 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700496 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700497 main.log.warn( "Timeout when testing cli responsiveness" )
498 main.log.debug( self.handle.before )
499 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700500 self.handle.expect( "onos>" )
501
Jon Hall14a03b52016-05-11 12:07:30 -0700502 if debug:
503 # NOTE: This adds and average of .4 seconds per call
504 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700505 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 self.handle.sendline( cmdStr )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700507 if dollarSign:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700508 i = self.handle.expect( [ "onos>" ], timeout )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700509 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700510 i = self.handle.expect( [ "onos>", self.prompt ], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800511 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800512 # TODO: do something with i
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000513 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800514 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700515 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700516 main.log.debug( self.name + ": Raw output" )
517 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700518
519 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800520 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800521 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700522 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700523 main.log.debug( self.name + ": ansiEscape output" )
524 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700525
kelvin-onlabfb521662015-02-27 09:52:40 -0800526 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000527 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700528 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700529 main.log.debug( self.name + ": Removed extra returns " +
530 "from output" )
531 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700532
533 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800534 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700535 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700536 main.log.debug( self.name + ": parsed and stripped output" )
537 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700538
Jon Hall63604932015-02-26 17:09:50 -0800539 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700540 output = response.split( cmdStr.strip(), 1 )
541 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700542 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700543 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700544 main.log.debug( self.name + ": " + repr( r ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700545 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800546 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800547 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800548 return output
GlennRCed771242016-01-13 17:02:47 -0800549 except pexpect.TIMEOUT:
550 main.log.error( self.name + ":ONOS timeout" )
551 if debug:
552 main.log.debug( self.handle.before )
553 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700554 except IndexError:
555 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700556 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700557 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800558 except TypeError:
559 main.log.exception( self.name + ": Object not as expected" )
560 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400561 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800562 main.log.error( self.name + ": EOF exception found" )
563 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700564 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700565 return None
566 else:
Devin Lim44075962017-08-11 10:56:37 -0700567 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800568 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800569 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700570 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700571 return None
572 else:
Devin Lim44075962017-08-11 10:56:37 -0700573 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400574
kelvin8ec71442015-01-15 16:57:00 -0800575 # IMPORTANT NOTE:
576 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800577 # the cli command changing 'a:b' with 'aB'.
578 # Ex ) onos:topology > onosTopology
579 # onos:links > onosLinks
580 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800581
kelvin-onlabd3b64892015-01-20 13:26:24 -0800582 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800583 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400584 Adds a new cluster node by ID and address information.
585 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800586 * nodeId
587 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400588 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800589 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800590 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400591 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800592 cmdStr = "add-node " + str( nodeId ) + " " +\
593 str( ONOSIp ) + " " + str( tcpPort )
594 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700595 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800596 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800597 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800598 main.log.error( "Error in adding node" )
599 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800600 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400601 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400603 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800604 except AssertionError:
605 main.log.exception( "" )
606 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800607 except TypeError:
608 main.log.exception( self.name + ": Object not as expected" )
609 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400610 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800611 main.log.error( self.name + ": EOF exception found" )
612 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700613 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800614 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800615 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700616 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400617
kelvin-onlabd3b64892015-01-20 13:26:24 -0800618 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800619 """
andrewonlab86dc3082014-10-13 18:18:38 -0400620 Removes a cluster by ID
621 Issues command: 'remove-node [<node-id>]'
622 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800623 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800624 """
andrewonlab86dc3082014-10-13 18:18:38 -0400625 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400626
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700628 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700629 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800630 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700631 if re.search( "Error", handle ):
632 main.log.error( "Error in removing node" )
633 main.log.error( handle )
634 return main.FALSE
635 else:
636 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800637 except AssertionError:
638 main.log.exception( "" )
639 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800640 except TypeError:
641 main.log.exception( self.name + ": Object not as expected" )
642 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400643 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800644 main.log.error( self.name + ": EOF exception found" )
645 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700646 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800647 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800648 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700649 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400650
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700651 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800652 """
andrewonlab7c211572014-10-15 16:45:20 -0400653 List the nodes currently visible
654 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700655 Optional argument:
656 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800657 """
andrewonlab7c211572014-10-15 16:45:20 -0400658 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700659 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700660 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700661 cmdStr += " -j"
662 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700663 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800664 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700665 return output
Jon Hallc6793552016-01-19 14:18:37 -0800666 except AssertionError:
667 main.log.exception( "" )
668 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800669 except TypeError:
670 main.log.exception( self.name + ": Object not as expected" )
671 return None
andrewonlab7c211572014-10-15 16:45:20 -0400672 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800673 main.log.error( self.name + ": EOF exception found" )
674 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700675 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800676 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800677 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700678 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400679
kelvin8ec71442015-01-15 16:57:00 -0800680 def topology( self ):
681 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700682 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700683 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700684 Return:
685 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800686 """
andrewonlab95ce8322014-10-13 14:12:04 -0400687 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700688 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800690 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800691 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700692 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400693 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800694 except AssertionError:
695 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800696 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800697 except TypeError:
698 main.log.exception( self.name + ": Object not as expected" )
699 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400700 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800701 main.log.error( self.name + ": EOF exception found" )
702 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700703 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800704 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800705 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700706 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800707
jenkins7ead5a82015-03-13 10:28:21 -0700708 def deviceRemove( self, deviceId ):
709 """
710 Removes particular device from storage
711
712 TODO: refactor this function
713 """
714 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700715 cmdStr = "device-remove " + str( deviceId )
716 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800717 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800718 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700719 if re.search( "Error", handle ):
720 main.log.error( "Error in removing device" )
721 main.log.error( handle )
722 return main.FALSE
723 else:
724 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800725 except AssertionError:
726 main.log.exception( "" )
727 return None
jenkins7ead5a82015-03-13 10:28:21 -0700728 except TypeError:
729 main.log.exception( self.name + ": Object not as expected" )
730 return None
731 except pexpect.EOF:
732 main.log.error( self.name + ": EOF exception found" )
733 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700734 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700735 except Exception:
736 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700737 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700738
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800740 """
Jon Hall7b02d952014-10-17 20:14:54 -0400741 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400742 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800743 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800744 """
andrewonlab86dc3082014-10-13 18:18:38 -0400745 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700746 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700748 cmdStr += " -j"
749 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800750 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800751 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700752 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800753 except AssertionError:
754 main.log.exception( "" )
755 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800756 except TypeError:
757 main.log.exception( self.name + ": Object not as expected" )
758 return None
andrewonlab7c211572014-10-15 16:45:20 -0400759 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800760 main.log.error( self.name + ": EOF exception found" )
761 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700762 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800763 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800764 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700765 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400766
kelvin-onlabd3b64892015-01-20 13:26:24 -0800767 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800768 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800769 This balances the devices across all controllers
770 by issuing command: 'onos> onos:balance-masters'
771 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800772 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800773 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800774 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700775 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800776 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800777 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700778 if re.search( "Error", handle ):
779 main.log.error( "Error in balancing masters" )
780 main.log.error( handle )
781 return main.FALSE
782 else:
783 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800784 except AssertionError:
785 main.log.exception( "" )
786 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800787 except TypeError:
788 main.log.exception( self.name + ": Object not as expected" )
789 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800790 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800791 main.log.error( self.name + ": EOF exception found" )
792 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700793 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800794 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800795 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700796 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800797
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000798 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700799 """
800 Returns the output of the masters command.
801 Optional argument:
802 * jsonFormat - boolean indicating if you want output in json
803 """
804 try:
805 cmdStr = "onos:masters"
806 if jsonFormat:
807 cmdStr += " -j"
808 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700809 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800810 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700811 return output
Jon Hallc6793552016-01-19 14:18:37 -0800812 except AssertionError:
813 main.log.exception( "" )
814 return None
acsmars24950022015-07-30 18:00:43 -0700815 except TypeError:
816 main.log.exception( self.name + ": Object not as expected" )
817 return None
818 except pexpect.EOF:
819 main.log.error( self.name + ": EOF exception found" )
820 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700821 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700822 except Exception:
823 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700824 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700825
Jon Hallc6793552016-01-19 14:18:37 -0800826 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700827 """
828 Uses the master command to check that the devices' leadership
829 is evenly divided
830
831 Dependencies: checkMasters() and summary()
832
Jon Hall6509dbf2016-06-21 17:01:17 -0700833 Returns main.TRUE if the devices are balanced
834 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700835 Exits on Exception
836 Returns None on TypeError
837 """
838 try:
Jon Hallc6793552016-01-19 14:18:37 -0800839 summaryOutput = self.summary()
840 totalDevices = json.loads( summaryOutput )[ "devices" ]
841 except ( TypeError, ValueError ):
842 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
843 return None
844 try:
acsmars24950022015-07-30 18:00:43 -0700845 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800846 mastersOutput = self.checkMasters()
847 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700848 first = masters[ 0 ][ "size" ]
849 for master in masters:
850 totalOwnedDevices += master[ "size" ]
851 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
852 main.log.error( "Mastership not balanced" )
853 main.log.info( "\n" + self.checkMasters( False ) )
854 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700855 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700856 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700857 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800858 except ( TypeError, ValueError ):
859 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700860 return None
861 except pexpect.EOF:
862 main.log.error( self.name + ": EOF exception found" )
863 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700864 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700865 except Exception:
866 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700867 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700868
YPZhangfebf7302016-05-24 16:45:56 -0700869 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800870 """
Jon Halle8217482014-10-17 13:49:14 -0400871 Lists all core links
872 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800873 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800874 """
Jon Halle8217482014-10-17 13:49:14 -0400875 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700876 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800877 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700878 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700879 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800880 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800881 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700882 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800883 except AssertionError:
884 main.log.exception( "" )
885 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800886 except TypeError:
887 main.log.exception( self.name + ": Object not as expected" )
888 return None
Jon Halle8217482014-10-17 13:49:14 -0400889 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800890 main.log.error( self.name + ": EOF exception found" )
891 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700892 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800893 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800894 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700895 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400896
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800898 """
Jon Halle8217482014-10-17 13:49:14 -0400899 Lists all ports
900 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800901 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800902 """
Jon Halle8217482014-10-17 13:49:14 -0400903 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700904 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800905 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700906 cmdStr += " -j"
907 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800908 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800909 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700910 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800911 except AssertionError:
912 main.log.exception( "" )
913 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800914 except TypeError:
915 main.log.exception( self.name + ": Object not as expected" )
916 return None
Jon Halle8217482014-10-17 13:49:14 -0400917 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800918 main.log.error( self.name + ": EOF exception found" )
919 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700920 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800921 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800922 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700923 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400924
kelvin-onlabd3b64892015-01-20 13:26:24 -0800925 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800926 """
Jon Hall983a1702014-10-28 18:44:22 -0400927 Lists all devices and the controllers with roles assigned to them
928 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800929 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800930 """
andrewonlab7c211572014-10-15 16:45:20 -0400931 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700932 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800933 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700934 cmdStr += " -j"
935 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800936 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800937 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700938 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800939 except AssertionError:
940 main.log.exception( "" )
941 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800942 except TypeError:
943 main.log.exception( self.name + ": Object not as expected" )
944 return None
Jon Hall983a1702014-10-28 18:44:22 -0400945 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800946 main.log.error( self.name + ": EOF exception found" )
947 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700948 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800949 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800950 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700951 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -0400952
kelvin-onlabd3b64892015-01-20 13:26:24 -0800953 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800954 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800955 Given the a string containing the json representation of the "roles"
956 cli command and a partial or whole device id, returns a json object
957 containing the roles output for the first device whose id contains
958 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400959
960 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800961 A dict of the role assignments for the given device or
962 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800963 """
Jon Hall983a1702014-10-28 18:44:22 -0400964 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400966 return None
967 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800968 rawRoles = self.roles()
969 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800970 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800972 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800973 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400974 return device
975 return None
Jon Hallc6793552016-01-19 14:18:37 -0800976 except ( TypeError, ValueError ):
977 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800978 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400979 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800980 main.log.error( self.name + ": EOF exception found" )
981 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700982 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800983 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800984 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700985 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -0800986
kelvin-onlabd3b64892015-01-20 13:26:24 -0800987 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800988 """
Jon Hall94fd0472014-12-08 11:52:42 -0800989 Iterates through each device and checks if there is a master assigned
990 Returns: main.TRUE if each device has a master
991 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800992 """
Jon Hall94fd0472014-12-08 11:52:42 -0800993 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 rawRoles = self.roles()
995 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800996 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800997 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800998 # print device
999 if device[ 'master' ] == "none":
1000 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001001 return main.FALSE
1002 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001003 except ( TypeError, ValueError ):
1004 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001005 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001006 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001007 main.log.error( self.name + ": EOF exception found" )
1008 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001009 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001010 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001011 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001012 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001013
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001015 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001016 Returns string of paths, and the cost.
1017 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001018 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001019 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001020 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1021 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001022 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001023 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001024 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001025 main.log.error( "Error in getting paths" )
1026 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001027 else:
kelvin8ec71442015-01-15 16:57:00 -08001028 path = handle.split( ";" )[ 0 ]
1029 cost = handle.split( ";" )[ 1 ]
1030 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001031 except AssertionError:
1032 main.log.exception( "" )
1033 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001034 except TypeError:
1035 main.log.exception( self.name + ": Object not as expected" )
1036 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001037 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001038 main.log.error( self.name + ": EOF exception found" )
1039 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001040 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001041 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001042 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001043 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001044
kelvin-onlabd3b64892015-01-20 13:26:24 -08001045 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001046 """
Jon Hallffb386d2014-11-21 13:43:38 -08001047 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001048 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001049 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001050 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001051 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001052 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001054 cmdStr += " -j"
1055 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001056 if handle:
1057 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001058 # TODO: Maybe make this less hardcoded
1059 # ConsistentMap Exceptions
1060 assert "org.onosproject.store.service" not in handle
1061 # Node not leader
1062 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001063 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001064 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001065 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001066 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001067 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001068 except TypeError:
1069 main.log.exception( self.name + ": Object not as expected" )
1070 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001071 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001072 main.log.error( self.name + ": EOF exception found" )
1073 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001074 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001075 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001076 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001077 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001078
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001080 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001081 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001082
Jon Hallefbd9792015-03-05 16:11:36 -08001083 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001084 partial mac address
1085
Jon Hall42db6dc2014-10-24 19:03:48 -04001086 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001087 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001088 try:
kelvin8ec71442015-01-15 16:57:00 -08001089 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001090 return None
1091 else:
1092 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 rawHosts = self.hosts()
1094 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001095 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001097 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001098 if not host:
1099 pass
1100 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001101 return host
1102 return None
Jon Hallc6793552016-01-19 14:18:37 -08001103 except ( TypeError, ValueError ):
1104 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001105 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001106 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001107 main.log.error( self.name + ": EOF exception found" )
1108 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001109 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001110 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001111 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001112 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001113
kelvin-onlabd3b64892015-01-20 13:26:24 -08001114 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001115 """
1116 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001117 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001118
andrewonlab3f0a4af2014-10-17 12:25:14 -04001119 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001121 IMPORTANT:
1122 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001123 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001124 Furthermore, it assumes that value of VLAN is '-1'
1125 Description:
kelvin8ec71442015-01-15 16:57:00 -08001126 Converts mininet hosts ( h1, h2, h3... ) into
1127 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1128 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001129 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001130 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001131
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001133 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 hostHex = hex( int( host ) ).zfill( 12 )
1135 hostHex = str( hostHex ).replace( 'x', '0' )
1136 i = iter( str( hostHex ) )
1137 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1138 hostHex = hostHex + "/-1"
1139 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001140
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001142
Jon Halld4d4b372015-01-28 16:02:41 -08001143 except TypeError:
1144 main.log.exception( self.name + ": Object not as expected" )
1145 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001146 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001147 main.log.error( self.name + ": EOF exception found" )
1148 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001149 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001150 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001151 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001152 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001153
You Wang53dba1e2018-02-02 17:45:44 -08001154 def verifyHostIp( self, hostList=[], prefix="" ):
1155 """
1156 Description:
1157 Verify that all hosts have IP address assigned to them
1158 Optional:
1159 hostList: If specified, verifications only happen to the hosts
1160 in hostList
1161 prefix: at least one of the ip address assigned to the host
1162 needs to have the specified prefix
1163 Returns:
1164 main.TRUE if all hosts have specific IP address assigned;
1165 main.FALSE otherwise
1166 """
1167 import json
1168 try:
1169 hosts = self.hosts()
1170 hosts = json.loads( hosts )
1171 if not hostList:
1172 hostList = [ host[ "id" ] for host in hosts ]
1173 for host in hosts:
1174 hostId = host[ "id" ]
1175 if hostId not in hostList:
1176 continue
1177 ipList = host[ "ipAddresses" ]
1178 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1179 if not ipList:
1180 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1181 else:
1182 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1183 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1184 else:
1185 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1186 hostList.remove( hostId )
1187 if hostList:
1188 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1189 return main.FALSE
1190 else:
1191 return main.TRUE
1192 except KeyError:
1193 main.log.exception( self.name + ": host data not as expected: " + hosts )
1194 return None
1195 except pexpect.EOF:
1196 main.log.error( self.name + ": EOF exception found" )
1197 main.log.error( self.name + ": " + self.handle.before )
1198 main.cleanAndExit()
1199 except Exception:
1200 main.log.exception( self.name + ": Uncaught exception" )
1201 return None
1202
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001203 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001204 """
andrewonlabe6745342014-10-17 14:29:13 -04001205 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001206 * hostIdOne: ONOS host id for host1
1207 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001208 Optional:
1209 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001210 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001211 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001212 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001213 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001214 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001215 Returns:
1216 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001217 """
andrewonlabe6745342014-10-17 14:29:13 -04001218 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001219 cmdStr = "add-host-intent "
1220 if vlanId:
1221 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001222 if setVlan:
1223 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001224 if encap:
1225 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001226 if bandwidth:
1227 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001228 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001229 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001230 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001231 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001232 if re.search( "Error", handle ):
1233 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001234 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001235 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001236 else:
1237 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001238 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001239 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001240 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001241 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001242 else:
1243 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001244 main.log.debug( "Response from ONOS was: " +
1245 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001246 return None
Jon Hallc6793552016-01-19 14:18:37 -08001247 except AssertionError:
1248 main.log.exception( "" )
1249 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001250 except TypeError:
1251 main.log.exception( self.name + ": Object not as expected" )
1252 return None
andrewonlabe6745342014-10-17 14:29:13 -04001253 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001254 main.log.error( self.name + ": EOF exception found" )
1255 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001256 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001257 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001258 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001259 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001260
kelvin-onlabd3b64892015-01-20 13:26:24 -08001261 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001262 """
andrewonlab7b31d232014-10-24 13:31:47 -04001263 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001264 * ingressDevice: device id of ingress device
1265 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001266 Optional:
1267 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001268 Description:
1269 Adds an optical intent by specifying an ingress and egress device
1270 Returns:
1271 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001272 """
andrewonlab7b31d232014-10-24 13:31:47 -04001273 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001274 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1275 " " + str( egressDevice )
1276 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001277 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001278 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001279 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001280 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001281 main.log.error( "Error in adding Optical intent" )
1282 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001283 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001284 main.log.info( "Optical intent installed between " +
1285 str( ingressDevice ) + " and " +
1286 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001287 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001288 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001289 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001290 else:
1291 main.log.error( "Error, intent ID not found" )
1292 return None
Jon Hallc6793552016-01-19 14:18:37 -08001293 except AssertionError:
1294 main.log.exception( "" )
1295 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001296 except TypeError:
1297 main.log.exception( self.name + ": Object not as expected" )
1298 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001299 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001300 main.log.error( self.name + ": EOF exception found" )
1301 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001302 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001303 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001304 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001305 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001306
kelvin-onlabd3b64892015-01-20 13:26:24 -08001307 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001308 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001309 ingressDevice,
1310 egressDevice,
1311 portIngress="",
1312 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001313 ethType="",
1314 ethSrc="",
1315 ethDst="",
1316 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001317 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001318 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001319 ipProto="",
1320 ipSrc="",
1321 ipDst="",
1322 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001323 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001324 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001325 setVlan="",
1326 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001327 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001328 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001329 * ingressDevice: device id of ingress device
1330 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001331 Optional:
1332 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001333 * ethSrc: specify ethSrc ( i.e. src mac addr )
1334 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001335 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001336 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001337 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001338 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001339 * ipSrc: specify ip source address
1340 * ipDst: specify ip destination address
1341 * tcpSrc: specify tcp source port
1342 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001343 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001344 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001345 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001346 Description:
kelvin8ec71442015-01-15 16:57:00 -08001347 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001348 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001349 Returns:
1350 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001351
Jon Halle3f39ff2015-01-13 11:50:53 -08001352 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001353 options developers provide for point-to-point
1354 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001355 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001356 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001357 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001358
Jeremy Songsterff553672016-05-12 17:06:23 -07001359 if ethType:
1360 cmd += " --ethType " + str( ethType )
1361 if ethSrc:
1362 cmd += " --ethSrc " + str( ethSrc )
1363 if ethDst:
1364 cmd += " --ethDst " + str( ethDst )
1365 if bandwidth:
1366 cmd += " --bandwidth " + str( bandwidth )
1367 if lambdaAlloc:
1368 cmd += " --lambda "
1369 if ipProto:
1370 cmd += " --ipProto " + str( ipProto )
1371 if ipSrc:
1372 cmd += " --ipSrc " + str( ipSrc )
1373 if ipDst:
1374 cmd += " --ipDst " + str( ipDst )
1375 if tcpSrc:
1376 cmd += " --tcpSrc " + str( tcpSrc )
1377 if tcpDst:
1378 cmd += " --tcpDst " + str( tcpDst )
1379 if vlanId:
1380 cmd += " -v " + str( vlanId )
1381 if setVlan:
1382 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001383 if encap:
1384 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001385 if protected:
1386 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001387
kelvin8ec71442015-01-15 16:57:00 -08001388 # Check whether the user appended the port
1389 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001390 if "/" in ingressDevice:
1391 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001392 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001393 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001394 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001395 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001396 # Would it make sense to throw an exception and exit
1397 # the test?
1398 return None
andrewonlab36af3822014-11-18 17:48:18 -05001399
kelvin8ec71442015-01-15 16:57:00 -08001400 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001401 str( ingressDevice ) + "/" +\
1402 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001403
kelvin-onlabd3b64892015-01-20 13:26:24 -08001404 if "/" in egressDevice:
1405 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001406 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001407 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001408 main.log.error( "You must specify the egress port" )
1409 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001410
kelvin8ec71442015-01-15 16:57:00 -08001411 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001412 str( egressDevice ) + "/" +\
1413 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001414
kelvin-onlab898a6c62015-01-16 14:13:53 -08001415 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001416 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001417 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001418 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001419 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001420 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001421 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001422 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001423 # TODO: print out all the options in this message?
1424 main.log.info( "Point-to-point intent installed between " +
1425 str( ingressDevice ) + " and " +
1426 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001427 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001428 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001429 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001430 else:
1431 main.log.error( "Error, intent ID not found" )
1432 return None
Jon Hallc6793552016-01-19 14:18:37 -08001433 except AssertionError:
1434 main.log.exception( "" )
1435 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001436 except TypeError:
1437 main.log.exception( self.name + ": Object not as expected" )
1438 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001439 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001440 main.log.error( self.name + ": EOF exception found" )
1441 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001442 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001443 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001444 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001445 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001446
kelvin-onlabd3b64892015-01-20 13:26:24 -08001447 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001448 self,
shahshreyac2f97072015-03-19 17:04:29 -07001449 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001450 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001451 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001452 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001453 ethType="",
1454 ethSrc="",
1455 ethDst="",
1456 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001457 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001458 ipProto="",
1459 ipSrc="",
1460 ipDst="",
1461 tcpSrc="",
1462 tcpDst="",
1463 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001464 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001465 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001466 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001467 partial=False,
1468 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001469 """
shahshreyad0c80432014-12-04 16:56:05 -08001470 Note:
shahshreya70622b12015-03-19 17:19:00 -07001471 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001472 is same. That is, all ingress devices include port numbers
1473 with a "/" or all ingress devices could specify device
1474 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001475 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001476 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001477 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001478 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001479 Optional:
1480 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001481 * ethSrc: specify ethSrc ( i.e. src mac addr )
1482 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001483 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001484 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001485 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001486 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001487 * ipSrc: specify ip source address
1488 * ipDst: specify ip destination address
1489 * tcpSrc: specify tcp source port
1490 * tcpDst: specify tcp destination port
1491 * setEthSrc: action to Rewrite Source MAC Address
1492 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001493 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001494 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001495 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001496 Description:
kelvin8ec71442015-01-15 16:57:00 -08001497 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001498 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001499 Returns:
1500 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001501
Jon Halle3f39ff2015-01-13 11:50:53 -08001502 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001503 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001504 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001505 """
shahshreyad0c80432014-12-04 16:56:05 -08001506 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001507 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001508
Jeremy Songsterff553672016-05-12 17:06:23 -07001509 if ethType:
1510 cmd += " --ethType " + str( ethType )
1511 if ethSrc:
1512 cmd += " --ethSrc " + str( ethSrc )
1513 if ethDst:
1514 cmd += " --ethDst " + str( ethDst )
1515 if bandwidth:
1516 cmd += " --bandwidth " + str( bandwidth )
1517 if lambdaAlloc:
1518 cmd += " --lambda "
1519 if ipProto:
1520 cmd += " --ipProto " + str( ipProto )
1521 if ipSrc:
1522 cmd += " --ipSrc " + str( ipSrc )
1523 if ipDst:
1524 cmd += " --ipDst " + str( ipDst )
1525 if tcpSrc:
1526 cmd += " --tcpSrc " + str( tcpSrc )
1527 if tcpDst:
1528 cmd += " --tcpDst " + str( tcpDst )
1529 if setEthSrc:
1530 cmd += " --setEthSrc " + str( setEthSrc )
1531 if setEthDst:
1532 cmd += " --setEthDst " + str( setEthDst )
1533 if vlanId:
1534 cmd += " -v " + str( vlanId )
1535 if setVlan:
1536 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001537 if partial:
1538 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001539 if encap:
1540 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001541
kelvin8ec71442015-01-15 16:57:00 -08001542 # Check whether the user appended the port
1543 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001544
1545 if portIngressList is None:
1546 for ingressDevice in ingressDeviceList:
1547 if "/" in ingressDevice:
1548 cmd += " " + str( ingressDevice )
1549 else:
1550 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001551 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001552 # TODO: perhaps more meaningful return
1553 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001554 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001555 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001556 for ingressDevice, portIngress in zip( ingressDeviceList,
1557 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001558 cmd += " " + \
1559 str( ingressDevice ) + "/" +\
1560 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001561 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001562 main.log.error( "Device list and port list does not " +
1563 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001564 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001565 if "/" in egressDevice:
1566 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001567 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001568 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001569 main.log.error( "You must specify " +
1570 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001571 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001572
kelvin8ec71442015-01-15 16:57:00 -08001573 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 str( egressDevice ) + "/" +\
1575 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001576 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001577 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001578 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001579 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001580 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001581 main.log.error( "Error in adding multipoint-to-singlepoint " +
1582 "intent" )
1583 return None
shahshreyad0c80432014-12-04 16:56:05 -08001584 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001585 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001586 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001587 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001588 else:
1589 main.log.error( "Error, intent ID not found" )
1590 return None
Jon Hallc6793552016-01-19 14:18:37 -08001591 except AssertionError:
1592 main.log.exception( "" )
1593 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001594 except TypeError:
1595 main.log.exception( self.name + ": Object not as expected" )
1596 return None
1597 except pexpect.EOF:
1598 main.log.error( self.name + ": EOF exception found" )
1599 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001600 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001601 except Exception:
1602 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001603 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001604
1605 def addSinglepointToMultipointIntent(
1606 self,
1607 ingressDevice,
1608 egressDeviceList,
1609 portIngress="",
1610 portEgressList=None,
1611 ethType="",
1612 ethSrc="",
1613 ethDst="",
1614 bandwidth="",
1615 lambdaAlloc=False,
1616 ipProto="",
1617 ipSrc="",
1618 ipDst="",
1619 tcpSrc="",
1620 tcpDst="",
1621 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001622 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001623 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001624 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001625 partial=False,
1626 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001627 """
1628 Note:
1629 This function assumes the format of all egress devices
1630 is same. That is, all egress devices include port numbers
1631 with a "/" or all egress devices could specify device
1632 ids and port numbers seperately.
1633 Required:
1634 * EgressDeviceList: List of device ids of egress device
1635 ( Atleast 2 eress devices required in the list )
1636 * ingressDevice: device id of ingress device
1637 Optional:
1638 * ethType: specify ethType
1639 * ethSrc: specify ethSrc ( i.e. src mac addr )
1640 * ethDst: specify ethDst ( i.e. dst mac addr )
1641 * bandwidth: specify bandwidth capacity of link
1642 * lambdaAlloc: if True, intent will allocate lambda
1643 for the specified intent
1644 * ipProto: specify ip protocol
1645 * ipSrc: specify ip source address
1646 * ipDst: specify ip destination address
1647 * tcpSrc: specify tcp source port
1648 * tcpDst: specify tcp destination port
1649 * setEthSrc: action to Rewrite Source MAC Address
1650 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001651 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001652 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001653 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001654 Description:
1655 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1656 specifying device id's and optional fields
1657 Returns:
1658 A string of the intent id or None on error
1659
1660 NOTE: This function may change depending on the
1661 options developers provide for singlepoint-to-multipoint
1662 intent via cli
1663 """
1664 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001665 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001666
Jeremy Songsterff553672016-05-12 17:06:23 -07001667 if ethType:
1668 cmd += " --ethType " + str( ethType )
1669 if ethSrc:
1670 cmd += " --ethSrc " + str( ethSrc )
1671 if ethDst:
1672 cmd += " --ethDst " + str( ethDst )
1673 if bandwidth:
1674 cmd += " --bandwidth " + str( bandwidth )
1675 if lambdaAlloc:
1676 cmd += " --lambda "
1677 if ipProto:
1678 cmd += " --ipProto " + str( ipProto )
1679 if ipSrc:
1680 cmd += " --ipSrc " + str( ipSrc )
1681 if ipDst:
1682 cmd += " --ipDst " + str( ipDst )
1683 if tcpSrc:
1684 cmd += " --tcpSrc " + str( tcpSrc )
1685 if tcpDst:
1686 cmd += " --tcpDst " + str( tcpDst )
1687 if setEthSrc:
1688 cmd += " --setEthSrc " + str( setEthSrc )
1689 if setEthDst:
1690 cmd += " --setEthDst " + str( setEthDst )
1691 if vlanId:
1692 cmd += " -v " + str( vlanId )
1693 if setVlan:
1694 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001695 if partial:
1696 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001697 if encap:
1698 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001699
1700 # Check whether the user appended the port
1701 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001702
kelvin-onlabb9408212015-04-01 13:34:04 -07001703 if "/" in ingressDevice:
1704 cmd += " " + str( ingressDevice )
1705 else:
1706 if not portIngress:
1707 main.log.error( "You must specify " +
1708 "the Ingress port" )
1709 return main.FALSE
1710
1711 cmd += " " +\
1712 str( ingressDevice ) + "/" +\
1713 str( portIngress )
1714
1715 if portEgressList is None:
1716 for egressDevice in egressDeviceList:
1717 if "/" in egressDevice:
1718 cmd += " " + str( egressDevice )
1719 else:
1720 main.log.error( "You must specify " +
1721 "the egress port" )
1722 # TODO: perhaps more meaningful return
1723 return main.FALSE
1724 else:
1725 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001726 for egressDevice, portEgress in zip( egressDeviceList,
1727 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001728 cmd += " " + \
1729 str( egressDevice ) + "/" +\
1730 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001731 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001732 main.log.error( "Device list and port list does not " +
1733 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001734 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001735 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001736 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001737 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001738 # If error, return error message
1739 if re.search( "Error", handle ):
1740 main.log.error( "Error in adding singlepoint-to-multipoint " +
1741 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001742 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001743 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001744 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001745 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001746 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001747 else:
1748 main.log.error( "Error, intent ID not found" )
1749 return None
Jon Hallc6793552016-01-19 14:18:37 -08001750 except AssertionError:
1751 main.log.exception( "" )
1752 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001753 except TypeError:
1754 main.log.exception( self.name + ": Object not as expected" )
1755 return None
shahshreyad0c80432014-12-04 16:56:05 -08001756 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001757 main.log.error( self.name + ": EOF exception found" )
1758 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001759 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001760 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001761 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001762 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001763
Hari Krishna9e232602015-04-13 17:29:08 -07001764 def addMplsIntent(
1765 self,
1766 ingressDevice,
1767 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001768 ingressPort="",
1769 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001770 ethType="",
1771 ethSrc="",
1772 ethDst="",
1773 bandwidth="",
1774 lambdaAlloc=False,
1775 ipProto="",
1776 ipSrc="",
1777 ipDst="",
1778 tcpSrc="",
1779 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001780 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001781 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001782 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001783 """
1784 Required:
1785 * ingressDevice: device id of ingress device
1786 * egressDevice: device id of egress device
1787 Optional:
1788 * ethType: specify ethType
1789 * ethSrc: specify ethSrc ( i.e. src mac addr )
1790 * ethDst: specify ethDst ( i.e. dst mac addr )
1791 * bandwidth: specify bandwidth capacity of link
1792 * lambdaAlloc: if True, intent will allocate lambda
1793 for the specified intent
1794 * ipProto: specify ip protocol
1795 * ipSrc: specify ip source address
1796 * ipDst: specify ip destination address
1797 * tcpSrc: specify tcp source port
1798 * tcpDst: specify tcp destination port
1799 * ingressLabel: Ingress MPLS label
1800 * egressLabel: Egress MPLS label
1801 Description:
1802 Adds MPLS intent by
1803 specifying device id's and optional fields
1804 Returns:
1805 A string of the intent id or None on error
1806
1807 NOTE: This function may change depending on the
1808 options developers provide for MPLS
1809 intent via cli
1810 """
1811 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001812 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001813
Jeremy Songsterff553672016-05-12 17:06:23 -07001814 if ethType:
1815 cmd += " --ethType " + str( ethType )
1816 if ethSrc:
1817 cmd += " --ethSrc " + str( ethSrc )
1818 if ethDst:
1819 cmd += " --ethDst " + str( ethDst )
1820 if bandwidth:
1821 cmd += " --bandwidth " + str( bandwidth )
1822 if lambdaAlloc:
1823 cmd += " --lambda "
1824 if ipProto:
1825 cmd += " --ipProto " + str( ipProto )
1826 if ipSrc:
1827 cmd += " --ipSrc " + str( ipSrc )
1828 if ipDst:
1829 cmd += " --ipDst " + str( ipDst )
1830 if tcpSrc:
1831 cmd += " --tcpSrc " + str( tcpSrc )
1832 if tcpDst:
1833 cmd += " --tcpDst " + str( tcpDst )
1834 if ingressLabel:
1835 cmd += " --ingressLabel " + str( ingressLabel )
1836 if egressLabel:
1837 cmd += " --egressLabel " + str( egressLabel )
1838 if priority:
1839 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001840
1841 # Check whether the user appended the port
1842 # or provided it as an input
1843 if "/" in ingressDevice:
1844 cmd += " " + str( ingressDevice )
1845 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001846 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001847 main.log.error( "You must specify the ingress port" )
1848 return None
1849
1850 cmd += " " + \
1851 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001852 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001853
1854 if "/" in egressDevice:
1855 cmd += " " + str( egressDevice )
1856 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001857 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001858 main.log.error( "You must specify the egress port" )
1859 return None
1860
1861 cmd += " " +\
1862 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001863 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001864
1865 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001866 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001867 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001868 # If error, return error message
1869 if re.search( "Error", handle ):
1870 main.log.error( "Error in adding mpls intent" )
1871 return None
1872 else:
1873 # TODO: print out all the options in this message?
1874 main.log.info( "MPLS intent installed between " +
1875 str( ingressDevice ) + " and " +
1876 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001877 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07001878 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001879 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07001880 else:
1881 main.log.error( "Error, intent ID not found" )
1882 return None
Jon Hallc6793552016-01-19 14:18:37 -08001883 except AssertionError:
1884 main.log.exception( "" )
1885 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001886 except TypeError:
1887 main.log.exception( self.name + ": Object not as expected" )
1888 return None
1889 except pexpect.EOF:
1890 main.log.error( self.name + ": EOF exception found" )
1891 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001892 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001893 except Exception:
1894 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001895 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001896
Jon Hallefbd9792015-03-05 16:11:36 -08001897 def removeIntent( self, intentId, app='org.onosproject.cli',
1898 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001899 """
shahshreya1c818fc2015-02-26 13:44:08 -08001900 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001901 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001902 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001903 -p or --purge: Purge the intent from the store after removal
1904
Jon Halle3f39ff2015-01-13 11:50:53 -08001905 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001906 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001907 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001908 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001909 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001910 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001911 if purge:
1912 cmdStr += " -p"
1913 if sync:
1914 cmdStr += " -s"
1915
1916 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001917 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001918 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001919 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001920 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001921 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001922 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001923 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001924 # TODO: Should this be main.TRUE
1925 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001926 except AssertionError:
1927 main.log.exception( "" )
1928 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001929 except TypeError:
1930 main.log.exception( self.name + ": Object not as expected" )
1931 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001932 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001933 main.log.error( self.name + ": EOF exception found" )
1934 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001935 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001936 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001937 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001938 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04001939
YPZhangfebf7302016-05-24 16:45:56 -07001940 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001941 """
1942 Description:
1943 Remove all the intents
1944 Optional args:-
1945 -s or --sync: Waits for the removal before returning
1946 -p or --purge: Purge the intent from the store after removal
1947 Returns:
1948 Returns main.TRUE if all intents are removed, otherwise returns
1949 main.FALSE; Returns None for exception
1950 """
1951 try:
1952 cmdStr = "remove-intent"
1953 if purge:
1954 cmdStr += " -p"
1955 if sync:
1956 cmdStr += " -s"
1957
1958 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001959 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001960 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08001961 assert "Command not found:" not in handle, handle
1962 if re.search( "Error", handle ):
1963 main.log.error( "Error in removing intent" )
1964 return main.FALSE
1965 else:
1966 return main.TRUE
1967 except AssertionError:
1968 main.log.exception( "" )
1969 return None
1970 except TypeError:
1971 main.log.exception( self.name + ": Object not as expected" )
1972 return None
1973 except pexpect.EOF:
1974 main.log.error( self.name + ": EOF exception found" )
1975 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001976 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001977 except Exception:
1978 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001979 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001980
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001981 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001982 """
1983 Purges all WITHDRAWN Intents
1984 """
1985 try:
1986 cmdStr = "purge-intents"
1987 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001988 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001989 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001990 if re.search( "Error", handle ):
1991 main.log.error( "Error in purging intents" )
1992 return main.FALSE
1993 else:
1994 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001995 except AssertionError:
1996 main.log.exception( "" )
1997 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001998 except TypeError:
1999 main.log.exception( self.name + ": Object not as expected" )
2000 return None
2001 except pexpect.EOF:
2002 main.log.error( self.name + ": EOF exception found" )
2003 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002004 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002005 except Exception:
2006 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002007 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002008
Devin Lime6fe3c42017-10-18 16:28:40 -07002009 def wipeout( self ):
2010 """
2011 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2012 """
2013 try:
2014 cmdStr = "wipe-out please"
2015 handle = self.sendline( cmdStr, timeout=60 )
2016 assert handle is not None, "Error in sendline"
2017 assert "Command not found:" not in handle, handle
2018 return main.TRUE
2019 except AssertionError:
2020 main.log.exception( "" )
2021 return None
2022 except TypeError:
2023 main.log.exception( self.name + ": Object not as expected" )
2024 return None
2025 except pexpect.EOF:
2026 main.log.error( self.name + ": EOF exception found" )
2027 main.log.error( self.name + ": " + self.handle.before )
2028 main.cleanAndExit()
2029 except Exception:
2030 main.log.exception( self.name + ": Uncaught exception!" )
2031 main.cleanAndExit()
2032
kelvin-onlabd3b64892015-01-20 13:26:24 -08002033 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002034 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002035 NOTE: This method should be used after installing application:
2036 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002037 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002038 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002039 Description:
2040 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002041 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002042 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002043 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002044 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002045 cmdStr += " -j"
2046 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002047 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002048 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002049 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002050 except AssertionError:
2051 main.log.exception( "" )
2052 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002053 except TypeError:
2054 main.log.exception( self.name + ": Object not as expected" )
2055 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002056 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002057 main.log.error( self.name + ": EOF exception found" )
2058 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002059 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002060 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002061 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002062 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002063
pingping-lin54b03372015-08-13 14:43:10 -07002064 def ipv4RouteNumber( self ):
2065 """
2066 NOTE: This method should be used after installing application:
2067 onos-app-sdnip
2068 Description:
2069 Obtain the total IPv4 routes number in the system
2070 """
2071 try:
Pratik Parab57963572017-05-09 11:37:54 -07002072 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002073 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002074 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002075 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002076 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002077 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002078 except AssertionError:
2079 main.log.exception( "" )
2080 return None
2081 except ( TypeError, ValueError ):
2082 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002083 return None
2084 except pexpect.EOF:
2085 main.log.error( self.name + ": EOF exception found" )
2086 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002087 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002088 except Exception:
2089 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002090 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002091
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002092 # =============Function to check Bandwidth allocation========
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002093 def allocations( self, jsonFormat = True, dollarSign = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002094 """
2095 Description:
2096 Obtain Bandwidth Allocation Information from ONOS cli.
2097 """
2098 try:
2099 cmdStr = "allocations"
2100 if jsonFormat:
2101 cmdStr += " -j"
2102 handle = self.sendline( cmdStr, timeout=300, dollarSign=True )
2103 assert handle is not None, "Error in sendline"
2104 assert "Command not found:" not in handle, handle
2105 return handle
2106 except AssertionError:
2107 main.log.exception( "" )
2108 return None
2109 except ( TypeError, ValueError ):
2110 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2111 return None
2112 except pexpect.EOF:
2113 main.log.error( self.name + ": EOF exception found" )
2114 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002115 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002116 except Exception:
2117 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002118 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002119
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002120 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002121 """
andrewonlabe6745342014-10-17 14:29:13 -04002122 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002123 Obtain intents from the ONOS cli.
2124 Optional:
2125 * jsonFormat: Enable output formatting in json, default to True
2126 * summary: Whether only output the intent summary, defaults to False
2127 * type: Only output a certain type of intent. This options is valid
2128 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002129 """
andrewonlabe6745342014-10-17 14:29:13 -04002130 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002131 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002132 if summary:
2133 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002134 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002135 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002136 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002137 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002138 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002139 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002140 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002141 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002142 else:
Jon Hallff566d52016-01-15 14:45:36 -08002143 intentType = ""
2144 # IF we want the summary of a specific intent type
2145 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002146 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002147 if intentType in jsonResult.keys():
2148 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002149 else:
Jon Hallff566d52016-01-15 14:45:36 -08002150 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002151 return handle
2152 else:
2153 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002154 except AssertionError:
2155 main.log.exception( "" )
2156 return None
2157 except ( TypeError, ValueError ):
2158 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002159 return None
2160 except pexpect.EOF:
2161 main.log.error( self.name + ": EOF exception found" )
2162 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002163 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002164 except Exception:
2165 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002166 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002167
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002168 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002169 """
You Wangfdcbfc42016-05-16 12:16:53 -07002170 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002171 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002172 list of intent IDs.
2173 Parameters:
2174 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002175 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002176 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002177 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002178 accepted.
2179 Returns a list of dictionaries if a list of intent IDs is accepted,
2180 and each dictionary maps 'id' to the Intent ID and 'state' to
2181 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002182 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002183
kelvin-onlab54400a92015-02-26 18:05:51 -08002184 try:
2185 state = "State is Undefined"
2186 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002187 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002188 else:
Jon Hallc6793552016-01-19 14:18:37 -08002189 rawJson = intentsJson
2190 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002191 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002192 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002193 if intentsId == intent[ 'id' ]:
2194 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002195 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002196 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002197 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002198 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002199 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002200 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002201 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002202 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002203 for intent in parsedIntentsJson:
2204 if intentsId[ i ] == intent[ 'id' ]:
2205 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002206 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002207 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002208 break
Jon Hallefbd9792015-03-05 16:11:36 -08002209 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002210 main.log.warn( "Could not find all intents in ONOS output" )
2211 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002212 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002213 else:
Jon Hall53158082017-05-18 11:17:00 -07002214 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002215 return None
Jon Hallc6793552016-01-19 14:18:37 -08002216 except ( TypeError, ValueError ):
2217 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002218 return None
2219 except pexpect.EOF:
2220 main.log.error( self.name + ": EOF exception found" )
2221 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002222 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002223 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002224 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002225 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002226
Jon Hallf539eb92017-05-22 17:18:42 -07002227 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002228 """
2229 Description:
2230 Check intents state
2231 Required:
2232 intentsId - List of intents ID to be checked
2233 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002234 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002235 state in the list.
2236 *NOTE: You can pass in a list of expected state,
2237 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002238 Return:
Jon Hall53158082017-05-18 11:17:00 -07002239 Returns main.TRUE only if all intent are the same as expected states,
2240 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002241 """
2242 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002243 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002244 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002245
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002246 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002247 intentsDict = []
2248 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002249 if isinstance( intentsId, types.StringType ) \
2250 and intent.get( 'id' ) == intentsId:
2251 intentsDict.append( intent )
2252 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002253 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002254 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002255
2256 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002257 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002258 "getting intents state" )
2259 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002260
2261 if isinstance( expectedState, types.StringType ):
2262 for intents in intentsDict:
2263 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002264 main.log.debug( self.name + " : Intent ID - " +
2265 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002266 " actual state = " +
2267 intents.get( 'state' )
2268 + " does not equal expected state = "
2269 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002270 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002271 elif isinstance( expectedState, types.ListType ):
2272 for intents in intentsDict:
2273 if not any( state == intents.get( 'state' ) for state in
2274 expectedState ):
2275 main.log.debug( self.name + " : Intent ID - " +
2276 intents.get( 'id' ) +
2277 " actual state = " +
2278 intents.get( 'state' ) +
2279 " does not equal expected states = "
2280 + str( expectedState ) )
2281 returnValue = main.FALSE
2282
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002283 if returnValue == main.TRUE:
2284 main.log.info( self.name + ": All " +
2285 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002286 " intents are in " + str( expectedState ) +
2287 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002288 return returnValue
2289 except TypeError:
2290 main.log.exception( self.name + ": Object not as expected" )
2291 return None
2292 except pexpect.EOF:
2293 main.log.error( self.name + ": EOF exception found" )
2294 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002295 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002296 except Exception:
2297 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002298 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002299
Jon Hallf539eb92017-05-22 17:18:42 -07002300 def compareBandwidthAllocations( self, expectedAllocations ):
2301 """
2302 Description:
2303 Compare the allocated bandwidth with the given allocations
2304 Required:
2305 expectedAllocations - The expected ONOS output of the allocations command
2306 Return:
2307 Returns main.TRUE only if all intent are the same as expected states,
2308 otherwise returns main.FALSE.
2309 """
2310 # FIXME: Convert these string comparisons to object comparisons
2311 try:
2312 returnValue = main.TRUE
2313 bandwidthFailed = False
2314 rawAlloc = self.allocations()
2315 expectedFormat = StringIO( expectedAllocations )
2316 ONOSOutput = StringIO( rawAlloc )
2317 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2318 str( expectedFormat ) ) )
2319
2320 for actual, expected in izip( ONOSOutput, expectedFormat ):
2321 actual = actual.rstrip()
2322 expected = expected.rstrip()
2323 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2324 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002325 marker1 = actual.find( 'allocated' )
2326 m1 = actual[ :marker1 ]
2327 marker2 = expected.find( 'allocated' )
2328 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002329 if m1 != m2:
2330 bandwidthFailed = True
2331 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2332 bandwidthFailed = True
2333 expectedFormat.close()
2334 ONOSOutput.close()
2335
2336 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002337 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002338 returnValue = main.FALSE
2339 return returnValue
2340 except TypeError:
2341 main.log.exception( self.name + ": Object not as expected" )
2342 return None
2343 except pexpect.EOF:
2344 main.log.error( self.name + ": EOF exception found" )
2345 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002346 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002347 except Exception:
2348 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002349 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002350
You Wang66518af2016-05-16 15:32:59 -07002351 def compareIntent( self, intentDict ):
2352 """
2353 Description:
2354 Compare the intent ids and states provided in the argument with all intents in ONOS
2355 Return:
2356 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2357 Arguments:
2358 intentDict: a dictionary which maps intent ids to intent states
2359 """
2360 try:
2361 intentsRaw = self.intents()
2362 intentsJson = json.loads( intentsRaw )
2363 intentDictONOS = {}
2364 for intent in intentsJson:
2365 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002366 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002367 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002368 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002369 str( len( intentDict ) ) + " expected and " +
2370 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002371 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002372 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002373 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002374 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2375 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002376 else:
2377 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2378 main.log.debug( self.name + ": intent ID - " + intentID +
2379 " expected state is " + intentDict[ intentID ] +
2380 " but actual state is " + intentDictONOS[ intentID ] )
2381 returnValue = main.FALSE
2382 intentDictONOS.pop( intentID )
2383 if len( intentDictONOS ) > 0:
2384 returnValue = main.FALSE
2385 for intentID in intentDictONOS.keys():
2386 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002387 if returnValue == main.TRUE:
2388 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2389 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002390 except KeyError:
2391 main.log.exception( self.name + ": KeyError exception found" )
2392 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002393 except ( TypeError, ValueError ):
2394 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002395 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002396 except pexpect.EOF:
2397 main.log.error( self.name + ": EOF exception found" )
2398 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002399 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002400 except Exception:
2401 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002402 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002403
YPZhang14a4aa92016-07-15 13:37:15 -07002404 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002405 """
2406 Description:
2407 Check the number of installed intents.
2408 Optional:
2409 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002410 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002411 Return:
2412 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2413 , otherwise, returns main.FALSE.
2414 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002415
GlennRCed771242016-01-13 17:02:47 -08002416 try:
2417 cmd = "intents -s -j"
2418
2419 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002420 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002421 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002422 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002423 response = json.loads( response )
2424
2425 # get total and installed number, see if they are match
2426 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002427 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002428 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2429 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002430 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002431 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2432 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002433 return main.FALSE
2434
Jon Hallc6793552016-01-19 14:18:37 -08002435 except ( TypeError, ValueError ):
2436 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002437 return None
2438 except pexpect.EOF:
2439 main.log.error( self.name + ": EOF exception found" )
2440 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002441 if noExit:
2442 return main.FALSE
2443 else:
Devin Lim44075962017-08-11 10:56:37 -07002444 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002445 except pexpect.TIMEOUT:
2446 main.log.error( self.name + ": ONOS timeout" )
2447 return None
GlennRCed771242016-01-13 17:02:47 -08002448 except Exception:
2449 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002450 if noExit:
2451 return main.FALSE
2452 else:
Devin Lim44075962017-08-11 10:56:37 -07002453 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002454
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002455 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002456 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002457 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002458 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002459 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002460 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002461 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002462 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002463 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002464 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002465 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002466 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002467 if noCore:
2468 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002469 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002470 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002471 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002472 assert "Command not found:" not in handle, handle
2473 if re.search( "Error:", handle ):
2474 main.log.error( self.name + ": flows() response: " +
2475 str( handle ) )
2476 return handle
2477 except AssertionError:
2478 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002479 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002480 except TypeError:
2481 main.log.exception( self.name + ": Object not as expected" )
2482 return None
Jon Hallc6793552016-01-19 14:18:37 -08002483 except pexpect.TIMEOUT:
2484 main.log.error( self.name + ": ONOS timeout" )
2485 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002486 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002487 main.log.error( self.name + ": EOF exception found" )
2488 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002489 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002490 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002491 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002492 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002493
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002494 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002495 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002496 count = int( count ) if count else 0
2497 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002498
Jon Halle0f0b342017-04-18 11:43:47 -07002499 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002500 """
2501 Description:
GlennRCed771242016-01-13 17:02:47 -08002502 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002503 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2504 if the count of those states is 0, which means all current flows
2505 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002506 Optional:
GlennRCed771242016-01-13 17:02:47 -08002507 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002508 Return:
2509 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002510 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002511 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002512 """
2513 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002514 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002515 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002516 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002517 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002518 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002519 if rawFlows:
2520 # if we didn't get flows or flows function return None, we should return
2521 # main.Flase
2522 checkedStates.append( json.loads( rawFlows ) )
2523 else:
2524 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002525 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002526 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002527 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002528 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002529 except TypeError:
2530 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002531 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002532
GlennRCed771242016-01-13 17:02:47 -08002533 # We want to count PENDING_ADD if isPENDING is true
2534 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002535 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002536 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002537 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002538 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002539 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002540 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002541 except ( TypeError, ValueError ):
2542 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002543 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002544
YPZhang240842b2016-05-17 12:00:50 -07002545 except AssertionError:
2546 main.log.exception( "" )
2547 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002548 except pexpect.TIMEOUT:
2549 main.log.error( self.name + ": ONOS timeout" )
2550 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002551 except pexpect.EOF:
2552 main.log.error( self.name + ": EOF exception found" )
2553 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002554 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002555 except Exception:
2556 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002557 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002558
GlennRCed771242016-01-13 17:02:47 -08002559 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002560 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002561 """
andrewonlab87852b02014-11-19 18:44:19 -05002562 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002563 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002564 a specific point-to-point intent definition
2565 Required:
GlennRCed771242016-01-13 17:02:47 -08002566 * ingress: specify source dpid
2567 * egress: specify destination dpid
2568 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002569 Optional:
GlennRCed771242016-01-13 17:02:47 -08002570 * offset: the keyOffset is where the next batch of intents
2571 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002572 * noExit: If set to True, TestON will not exit if any error when issus command
2573 * getResponse: If set to True, function will return ONOS response.
2574
GlennRCed771242016-01-13 17:02:47 -08002575 Returns: If failed to push test intents, it will returen None,
2576 if successful, return true.
2577 Timeout expection will return None,
2578 TypeError will return false
2579 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002580 """
andrewonlab87852b02014-11-19 18:44:19 -05002581 try:
GlennRCed771242016-01-13 17:02:47 -08002582 if background:
2583 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002584 else:
GlennRCed771242016-01-13 17:02:47 -08002585 back = ""
2586 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002587 ingress,
2588 egress,
2589 batchSize,
2590 offset,
2591 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002592 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002593 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002594 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002595 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002596 if getResponse:
2597 return response
2598
GlennRCed771242016-01-13 17:02:47 -08002599 # TODO: We should handle if there is failure in installation
2600 return main.TRUE
2601
Jon Hallc6793552016-01-19 14:18:37 -08002602 except AssertionError:
2603 main.log.exception( "" )
2604 return None
GlennRCed771242016-01-13 17:02:47 -08002605 except pexpect.TIMEOUT:
2606 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002607 return None
andrewonlab87852b02014-11-19 18:44:19 -05002608 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002609 main.log.error( self.name + ": EOF exception found" )
2610 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002611 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002612 except TypeError:
2613 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002614 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002615 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002616 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002617 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002618
YPZhangebf9eb52016-05-12 15:20:24 -07002619 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002620 """
2621 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002622 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002623 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002624 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002625 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002626 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002627
YPZhangb5d3f832016-01-23 22:54:26 -08002628 try:
YPZhange3109a72016-02-02 11:25:37 -08002629 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002630 cmd = "flows -c added"
2631 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2632 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002633 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002634 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002635 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002636 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002637 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002638 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002639 return None
2640 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002641
You Wangd3cb2ce2016-05-16 14:01:24 -07002642 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002643 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002644 return None
2645 except pexpect.EOF:
2646 main.log.error( self.name + ": EOF exception found" )
2647 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002648 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002649 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002650 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002651 except pexpect.TIMEOUT:
2652 main.log.error( self.name + ": ONOS timeout" )
2653 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002654 except Exception:
2655 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002656 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002657 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002658 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002659
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002660 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002661 """
2662 Description:
2663 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002664 Optional:
2665 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002666 Return:
2667 The number of intents
2668 """
2669 try:
2670 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002671 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002672 if response is None:
2673 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002674 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002675 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002676 except ( TypeError, ValueError ):
2677 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002678 return None
2679 except pexpect.EOF:
2680 main.log.error( self.name + ": EOF exception found" )
2681 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002682 if noExit:
2683 return -1
2684 else:
Devin Lim44075962017-08-11 10:56:37 -07002685 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002686 except Exception:
2687 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002688 if noExit:
2689 return -1
2690 else:
Devin Lim44075962017-08-11 10:56:37 -07002691 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002692
kelvin-onlabd3b64892015-01-20 13:26:24 -08002693 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002694 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002695 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002696 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002697 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002698 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002699 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002700 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002701 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002702 cmdStr += " -j"
2703 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002704 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002705 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002706 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002707 except AssertionError:
2708 main.log.exception( "" )
2709 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002710 except TypeError:
2711 main.log.exception( self.name + ": Object not as expected" )
2712 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002713 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002714 main.log.error( self.name + ": EOF exception found" )
2715 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002716 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002717 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002718 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002719 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002720
kelvin-onlabd3b64892015-01-20 13:26:24 -08002721 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002722 """
2723 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002724 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002725 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002726 """
andrewonlab867212a2014-10-22 20:13:38 -04002727 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002728 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002729 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002730 cmdStr += " -j"
2731 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002732 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002733 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002734 if handle:
2735 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002736 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002737 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002738 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002739 else:
2740 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002741 except AssertionError:
2742 main.log.exception( "" )
2743 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002744 except TypeError:
2745 main.log.exception( self.name + ": Object not as expected" )
2746 return None
andrewonlab867212a2014-10-22 20:13:38 -04002747 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002748 main.log.error( self.name + ": EOF exception found" )
2749 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002750 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002751 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002752 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002753 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002754
kelvin8ec71442015-01-15 16:57:00 -08002755 # Wrapper functions ****************
2756 # Wrapper functions use existing driver
2757 # functions and extends their use case.
2758 # For example, we may use the output of
2759 # a normal driver function, and parse it
2760 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002761
kelvin-onlabd3b64892015-01-20 13:26:24 -08002762 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002763 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002764 Description:
2765 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002766 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002767 try:
kelvin8ec71442015-01-15 16:57:00 -08002768 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002769 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002770 if intentsStr is None:
2771 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002772 # Convert to a dictionary
2773 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002774 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002775 for intent in intents:
2776 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002777 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002778 except TypeError:
2779 main.log.exception( self.name + ": Object not as expected" )
2780 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002781 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002782 main.log.error( self.name + ": EOF exception found" )
2783 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002784 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002785 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002786 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002787 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002788
You Wang3c276252016-09-21 15:21:36 -07002789 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002790 """
2791 Determine the number of flow rules for the given device id that are
2792 in the added state
You Wang3c276252016-09-21 15:21:36 -07002793 Params:
2794 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002795 """
2796 try:
You Wang3c276252016-09-21 15:21:36 -07002797 if core:
2798 cmdStr = "flows any " + str( deviceId ) + " | " +\
2799 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2800 else:
2801 cmdStr = "flows any " + str( deviceId ) + " | " +\
2802 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002803 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002804 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002805 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002806 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002807 except AssertionError:
2808 main.log.exception( "" )
2809 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002810 except pexpect.EOF:
2811 main.log.error( self.name + ": EOF exception found" )
2812 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002813 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002814 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002815 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002816 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002817
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002818 def groupAddedCount( self, deviceId, core=False ):
2819 """
2820 Determine the number of group rules for the given device id that are
2821 in the added state
2822 Params:
2823 core: if True, only return the number of core groups added
2824 """
2825 try:
2826 if core:
2827 cmdStr = "groups any " + str( deviceId ) + " | " +\
2828 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2829 else:
2830 cmdStr = "groups any " + str( deviceId ) + " | " +\
2831 "grep 'state=ADDED' | wc -l"
2832 handle = self.sendline( cmdStr )
2833 assert handle is not None, "Error in sendline"
2834 assert "Command not found:" not in handle, handle
2835 return handle
2836 except AssertionError:
2837 main.log.exception( "" )
2838 return None
2839 except pexpect.EOF:
2840 main.log.error( self.name + ": EOF exception found" )
2841 main.log.error( self.name + ": " + self.handle.before )
2842 main.cleanAndExit()
2843 except Exception:
2844 main.log.exception( self.name + ": Uncaught exception!" )
2845 main.cleanAndExit()
2846
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002847 def addStaticRoute( self, subnet, intf):
2848 """
2849 Adds a static route to onos.
2850 Params:
2851 subnet: The subnet reaching through this route
2852 intf: The interface this route is reachable through
2853 """
2854 try:
2855 cmdStr = "route-add " + subnet + " " + intf
2856 handle = self.sendline( cmdStr )
2857 assert handle is not None, "Error in sendline"
2858 assert "Command not found:" not in handle, handle
2859 return handle
2860 except AssertionError:
2861 main.log.exception( "" )
2862 return None
2863 except pexpect.EOF:
2864 main.log.error( self.name + ": EOF exception found" )
2865 main.log.error( self.name + ": " + self.handle.before )
2866 main.cleanAndExit()
2867 except Exception:
2868 main.log.exception( self.name + ": Uncaught exception!" )
2869 main.cleanAndExit()
2870
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002871 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
2872 """
2873 Description:
2874 Check whether the number of groups for the given device id that
2875 are in ADDED state is bigger than minGroupCount.
2876 Required:
2877 * deviceId: device id to check the number of added group rules
2878 Optional:
2879 * minGroupCount: the number of groups to compare
2880 * core: if True, only check the number of core groups added
2881 * comparison: if 0, compare with greater than minFlowCount
2882 * if 1, compare with equal to minFlowCount
2883 Return:
2884 Returns the number of groups if it is bigger than minGroupCount,
2885 returns main.FALSE otherwise.
2886 """
2887 count = self.groupAddedCount( deviceId, core )
2888 count = int( count ) if count else 0
2889 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
2890
2891 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002892 """
2893 Description:
2894 Check whether the number of flow rules for the given device id that
2895 are in ADDED state is bigger than minFlowCount.
2896 Required:
2897 * deviceId: device id to check the number of added flow rules
2898 Optional:
2899 * minFlowCount: the number of flow rules to compare
2900 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002901 * comparison: if 0, compare with greater than minFlowCount
2902 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002903 Return:
2904 Returns the number of flow rules if it is bigger than minFlowCount,
2905 returns main.FALSE otherwise.
2906 """
2907 count = self.flowAddedCount( deviceId, core )
2908 count = int( count ) if count else 0
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002909 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002910
kelvin-onlabd3b64892015-01-20 13:26:24 -08002911 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002912 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002913 Use 'devices' function to obtain list of all devices
2914 and parse the result to obtain a list of all device
2915 id's. Returns this list. Returns empty list if no
2916 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002917 List is ordered sequentially
2918
andrewonlab3e15ead2014-10-15 14:21:34 -04002919 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002920 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002921 the ids. By obtaining the list of device ids on the fly,
2922 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002923 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002924 try:
kelvin8ec71442015-01-15 16:57:00 -08002925 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002926 devicesStr = self.devices( jsonFormat=False )
2927 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002928
kelvin-onlabd3b64892015-01-20 13:26:24 -08002929 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002930 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002931 return idList
kelvin8ec71442015-01-15 16:57:00 -08002932
2933 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002934 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002935 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002936 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002937 # Split list further into arguments before and after string
2938 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002939 # append to idList
2940 for arg in tempList:
2941 idList.append( arg.split( "id=" )[ 1 ] )
2942 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002943
Jon Halld4d4b372015-01-28 16:02:41 -08002944 except TypeError:
2945 main.log.exception( self.name + ": Object not as expected" )
2946 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002947 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002948 main.log.error( self.name + ": EOF exception found" )
2949 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002950 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002951 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002952 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002953 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002954
kelvin-onlabd3b64892015-01-20 13:26:24 -08002955 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002956 """
andrewonlab7c211572014-10-15 16:45:20 -04002957 Uses 'nodes' function to obtain list of all nodes
2958 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002959 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002960 Returns:
2961 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002962 """
andrewonlab7c211572014-10-15 16:45:20 -04002963 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002964 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002965 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002966 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002967 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002968 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002969 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002970 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002971 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002972 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002973 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002974 except ( TypeError, ValueError ):
2975 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002976 return None
andrewonlab7c211572014-10-15 16:45:20 -04002977 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002978 main.log.error( self.name + ": EOF exception found" )
2979 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002980 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002981 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002982 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002983 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002984
kelvin-onlabd3b64892015-01-20 13:26:24 -08002985 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002986 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002987 Return the first device from the devices api whose 'id' contains 'dpid'
2988 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002989 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002990 try:
kelvin8ec71442015-01-15 16:57:00 -08002991 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002992 return None
2993 else:
kelvin8ec71442015-01-15 16:57:00 -08002994 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002995 rawDevices = self.devices()
2996 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002997 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002998 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002999 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3000 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003001 return device
3002 return None
Jon Hallc6793552016-01-19 14:18:37 -08003003 except ( TypeError, ValueError ):
3004 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003005 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003006 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003007 main.log.error( self.name + ": EOF exception found" )
3008 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003009 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003010 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003011 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003012 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003013
You Wang24139872016-05-03 11:48:47 -07003014 def getTopology( self, topologyOutput ):
3015 """
3016 Definition:
3017 Loads a json topology output
3018 Return:
3019 topology = current ONOS topology
3020 """
3021 import json
3022 try:
3023 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003024 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003025 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003026 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003027 except ( TypeError, ValueError ):
3028 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3029 return None
You Wang24139872016-05-03 11:48:47 -07003030 except pexpect.EOF:
3031 main.log.error( self.name + ": EOF exception found" )
3032 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003033 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003034 except Exception:
3035 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003036 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003037
Pier6a0c4de2018-03-18 16:01:30 -07003038 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003039 """
Jon Hallefbd9792015-03-05 16:11:36 -08003040 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003041 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003042 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003043
Flavio Castro82ee2f62016-06-07 15:04:12 -07003044 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003045 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003046 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003047 logLevel = level to log to.
3048 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003049
Jon Hallefbd9792015-03-05 16:11:36 -08003050 Returns: main.TRUE if the number of switches and links are correct,
3051 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003052 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003053 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003054 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003055 try:
You Wang13310252016-07-31 10:56:14 -07003056 summary = self.summary()
3057 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003058 except ( TypeError, ValueError ):
3059 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3060 return main.ERROR
3061 try:
3062 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003063 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003064 return main.ERROR
3065 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003066 # Is the number of switches is what we expected
3067 devices = topology.get( 'devices', False )
3068 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003069 nodes = summary.get( 'nodes', False )
3070 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003071 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003072 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003073 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003074 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003075 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3076 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003077 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003078 output = output + "The number of links and switches match "\
3079 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003080 result = main.TRUE
3081 else:
You Wang24139872016-05-03 11:48:47 -07003082 output = output + \
3083 "The number of links and switches does not match " + \
3084 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003085 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003086 output = output + "\n ONOS sees %i devices" % int( devices )
3087 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003088 if int( numolink ) > 0:
3089 output = output + "and %i links " % int( links )
3090 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003091 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003092 output = output + "and %i controllers " % int( nodes )
3093 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003094 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003095 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003096 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003097 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003098 else:
You Wang24139872016-05-03 11:48:47 -07003099 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003100 return result
Jon Hall42db6dc2014-10-24 19:03:48 -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()
Jon Hall1c9e8732014-10-27 19:29:27 -04003108
kelvin-onlabd3b64892015-01-20 13:26:24 -08003109 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003110 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003111 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003112 deviceId must be the id of a device as seen in the onos devices command
3113 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003114 role must be either master, standby, or none
3115
Jon Halle3f39ff2015-01-13 11:50:53 -08003116 Returns:
3117 main.TRUE or main.FALSE based on argument verification and
3118 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003119 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003120 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003121 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003122 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003123 cmdStr = "device-role " +\
3124 str( deviceId ) + " " +\
3125 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003126 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003127 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003128 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003129 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003130 if re.search( "Error", handle ):
3131 # end color output to escape any colours
3132 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003133 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003134 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003135 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003136 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003137 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003138 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003139 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003140 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003141 except AssertionError:
3142 main.log.exception( "" )
3143 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003144 except TypeError:
3145 main.log.exception( self.name + ": Object not as expected" )
3146 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003147 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003148 main.log.error( self.name + ": EOF exception found" )
3149 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003150 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003151 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003152 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003153 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003154
kelvin-onlabd3b64892015-01-20 13:26:24 -08003155 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003156 """
Jon Hall0dd09952018-04-19 09:59:11 -07003157 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003158 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003159 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003160 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003161 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003162 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003163 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003164 cmdStr += " -j"
3165 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003166 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003167 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003168 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003169 except AssertionError:
3170 main.log.exception( "" )
3171 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003172 except TypeError:
3173 main.log.exception( self.name + ": Object not as expected" )
3174 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003175 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003176 main.log.error( self.name + ": EOF exception found" )
3177 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003178 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003179 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003180 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003181 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003182
kelvin-onlabd3b64892015-01-20 13:26:24 -08003183 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003184 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003185 CLI command to get the current leader for the Election test application
3186 NOTE: Requires installation of the onos-app-election feature
3187 Returns: Node IP of the leader if one exists
3188 None if none exists
3189 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003190 """
Jon Hall94fd0472014-12-08 11:52:42 -08003191 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003192 cmdStr = "election-test-leader"
3193 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003194 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003195 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003196 # Leader
3197 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003198 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003199 nodeSearch = re.search( leaderPattern, response )
3200 if nodeSearch:
3201 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003202 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003203 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003204 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003205 # no leader
3206 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003207 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003208 nullSearch = re.search( nullPattern, response )
3209 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003210 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003211 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003212 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003213 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003214 main.log.error( "Error in electionTestLeader on " + self.name +
3215 ": " + "unexpected response" )
3216 main.log.error( repr( response ) )
3217 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003218 except AssertionError:
3219 main.log.exception( "" )
3220 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003221 except TypeError:
3222 main.log.exception( self.name + ": Object not as expected" )
3223 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003224 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003225 main.log.error( self.name + ": EOF exception found" )
3226 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003227 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003228 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003229 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003230 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003231
kelvin-onlabd3b64892015-01-20 13:26:24 -08003232 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003233 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003234 CLI command to run for leadership of the Election test application.
3235 NOTE: Requires installation of the onos-app-election feature
3236 Returns: Main.TRUE on success
3237 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003238 """
Jon Hall94fd0472014-12-08 11:52:42 -08003239 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003240 cmdStr = "election-test-run"
3241 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003242 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003243 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003244 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003245 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003246 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003247 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003248 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003249 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003250 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003251 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003252 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003253 main.log.error( "Error in electionTestRun on " + self.name +
3254 ": " + "unexpected response" )
3255 main.log.error( repr( response ) )
3256 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003257 except AssertionError:
3258 main.log.exception( "" )
3259 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003260 except TypeError:
3261 main.log.exception( self.name + ": Object not as expected" )
3262 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003263 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003264 main.log.error( self.name + ": EOF exception found" )
3265 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003266 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003267 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003268 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003269 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003270
kelvin-onlabd3b64892015-01-20 13:26:24 -08003271 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003272 """
Jon Hall94fd0472014-12-08 11:52:42 -08003273 * CLI command to withdraw the local node from leadership election for
3274 * the Election test application.
3275 #NOTE: Requires installation of the onos-app-election feature
3276 Returns: Main.TRUE on success
3277 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003278 """
Jon Hall94fd0472014-12-08 11:52:42 -08003279 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003280 cmdStr = "election-test-withdraw"
3281 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003282 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003283 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003284 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003285 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003286 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003287 if re.search( successPattern, response ):
3288 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003289 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003290 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003291 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003292 main.log.error( "Error in electionTestWithdraw on " +
3293 self.name + ": " + "unexpected response" )
3294 main.log.error( repr( response ) )
3295 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003296 except AssertionError:
3297 main.log.exception( "" )
3298 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003299 except TypeError:
3300 main.log.exception( self.name + ": Object not as expected" )
3301 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003302 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003303 main.log.error( self.name + ": EOF exception found" )
3304 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003305 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003306 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003307 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003308 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003309
kelvin8ec71442015-01-15 16:57:00 -08003310 def getDevicePortsEnabledCount( self, dpid ):
3311 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003312 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003313 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003314 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003315 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003316 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3317 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003318 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003319 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003320 if re.search( "No such device", output ):
3321 main.log.error( "Error in getting ports" )
3322 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003323 return output
Jon Hallc6793552016-01-19 14:18:37 -08003324 except AssertionError:
3325 main.log.exception( "" )
3326 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003327 except TypeError:
3328 main.log.exception( self.name + ": Object not as expected" )
3329 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003330 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003331 main.log.error( self.name + ": EOF exception found" )
3332 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003333 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003334 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003335 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003336 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003337
kelvin8ec71442015-01-15 16:57:00 -08003338 def getDeviceLinksActiveCount( self, dpid ):
3339 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003340 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003341 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003342 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003343 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003344 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3345 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003346 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003347 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003348 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003349 main.log.error( "Error in getting ports " )
3350 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003351 return output
Jon Hallc6793552016-01-19 14:18:37 -08003352 except AssertionError:
3353 main.log.exception( "" )
3354 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003355 except TypeError:
3356 main.log.exception( self.name + ": Object not as expected" )
3357 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003358 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003359 main.log.error( self.name + ": EOF exception found" )
3360 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003361 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003362 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003363 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003364 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003365
kelvin8ec71442015-01-15 16:57:00 -08003366 def getAllIntentIds( self ):
3367 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003368 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003369 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003370 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003371 cmdStr = "onos:intents | grep id="
3372 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003373 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003374 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003375 if re.search( "Error", output ):
3376 main.log.error( "Error in getting ports" )
3377 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003378 return output
Jon Hallc6793552016-01-19 14:18:37 -08003379 except AssertionError:
3380 main.log.exception( "" )
3381 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003382 except TypeError:
3383 main.log.exception( self.name + ": Object not as expected" )
3384 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003385 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003386 main.log.error( self.name + ": EOF exception found" )
3387 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003388 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003389 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003390 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003391 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003392
Jon Hall73509952015-02-24 16:42:56 -08003393 def intentSummary( self ):
3394 """
Jon Hallefbd9792015-03-05 16:11:36 -08003395 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003396 """
3397 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003398 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003399 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003400 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003401 states.append( intent.get( 'state', None ) )
3402 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003403 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003404 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003405 except ( TypeError, ValueError ):
3406 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003407 return None
3408 except pexpect.EOF:
3409 main.log.error( self.name + ": EOF exception found" )
3410 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003411 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003412 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003413 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003414 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003415
Jon Hall61282e32015-03-19 11:34:11 -07003416 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003417 """
3418 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003419 Optional argument:
3420 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003421 """
Jon Hall63604932015-02-26 17:09:50 -08003422 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003423 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003424 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003425 cmdStr += " -j"
3426 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003427 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003428 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003429 return output
Jon Hallc6793552016-01-19 14:18:37 -08003430 except AssertionError:
3431 main.log.exception( "" )
3432 return None
Jon Hall63604932015-02-26 17:09:50 -08003433 except TypeError:
3434 main.log.exception( self.name + ": Object not as expected" )
3435 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003436 except pexpect.EOF:
3437 main.log.error( self.name + ": EOF exception found" )
3438 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003439 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003440 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003441 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003442 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003443
acsmarsa4a4d1e2015-07-10 16:01:24 -07003444 def leaderCandidates( self, jsonFormat=True ):
3445 """
3446 Returns the output of the leaders -c command.
3447 Optional argument:
3448 * jsonFormat - boolean indicating if you want output in json
3449 """
3450 try:
3451 cmdStr = "onos:leaders -c"
3452 if jsonFormat:
3453 cmdStr += " -j"
3454 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003455 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003456 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003457 return output
Jon Hallc6793552016-01-19 14:18:37 -08003458 except AssertionError:
3459 main.log.exception( "" )
3460 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003461 except TypeError:
3462 main.log.exception( self.name + ": Object not as expected" )
3463 return None
3464 except pexpect.EOF:
3465 main.log.error( self.name + ": EOF exception found" )
3466 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003467 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003468 except Exception:
3469 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003470 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003471
Jon Hallc6793552016-01-19 14:18:37 -08003472 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003473 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003474 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003475 topic parameter and an empty list if the topic doesn't exist
3476 If no leader is elected leader in the returned list will be "none"
3477 Returns None if there is a type error processing the json object
3478 """
3479 try:
Jon Hall6e709752016-02-01 13:38:46 -08003480 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003481 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003482 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003483 assert "Command not found:" not in rawOutput, rawOutput
3484 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003485 results = []
3486 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003487 if dict[ "topic" ] == topic:
3488 leader = dict[ "leader" ]
3489 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003490 results.append( leader )
3491 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003492 return results
Jon Hallc6793552016-01-19 14:18:37 -08003493 except AssertionError:
3494 main.log.exception( "" )
3495 return None
3496 except ( TypeError, ValueError ):
3497 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003498 return None
3499 except pexpect.EOF:
3500 main.log.error( self.name + ": EOF exception found" )
3501 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003502 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003503 except Exception:
3504 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003505 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003506
Jon Hall61282e32015-03-19 11:34:11 -07003507 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003508 """
3509 Returns the output of the intent Pending map.
3510 """
Jon Hall63604932015-02-26 17:09:50 -08003511 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003512 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003513 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003514 cmdStr += " -j"
3515 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003516 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003517 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003518 return output
Jon Hallc6793552016-01-19 14:18:37 -08003519 except AssertionError:
3520 main.log.exception( "" )
3521 return None
Jon Hall63604932015-02-26 17:09:50 -08003522 except TypeError:
3523 main.log.exception( self.name + ": Object not as expected" )
3524 return None
3525 except pexpect.EOF:
3526 main.log.error( self.name + ": EOF exception found" )
3527 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003528 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003529 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003530 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003531 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003532
Jon Hall2c8959e2016-12-16 12:17:34 -08003533 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003534 """
3535 Returns the output of the raft partitions command for ONOS.
3536 """
Jon Hall61282e32015-03-19 11:34:11 -07003537 # Sample JSON
3538 # {
3539 # "leader": "tcp://10.128.30.11:7238",
3540 # "members": [
3541 # "tcp://10.128.30.11:7238",
3542 # "tcp://10.128.30.17:7238",
3543 # "tcp://10.128.30.13:7238",
3544 # ],
3545 # "name": "p1",
3546 # "term": 3
3547 # },
Jon Hall63604932015-02-26 17:09:50 -08003548 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003549 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003550 if candidates:
3551 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003552 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003553 cmdStr += " -j"
3554 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003555 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003556 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003557 return output
Jon Hallc6793552016-01-19 14:18:37 -08003558 except AssertionError:
3559 main.log.exception( "" )
3560 return None
Jon Hall63604932015-02-26 17:09:50 -08003561 except TypeError:
3562 main.log.exception( self.name + ": Object not as expected" )
3563 return None
3564 except pexpect.EOF:
3565 main.log.error( self.name + ": EOF exception found" )
3566 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003567 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003568 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003569 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003570 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003571
Jon Halle9f909e2016-09-23 10:43:12 -07003572 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003573 """
3574 Returns the output of the apps command for ONOS. This command lists
3575 information about installed ONOS applications
3576 """
3577 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003578 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003579 # "description":"ONOS OpenFlow protocol southbound providers",
3580 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003581 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003582 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003583 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003584 if summary:
3585 cmdStr += " -s"
3586 if active:
3587 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003588 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003589 cmdStr += " -j"
3590 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003591 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003592 assert "Command not found:" not in output, output
3593 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003594 return output
Jon Hallbe379602015-03-24 13:39:32 -07003595 # FIXME: look at specific exceptions/Errors
3596 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003597 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003598 return None
3599 except TypeError:
3600 main.log.exception( self.name + ": Object not as expected" )
3601 return None
3602 except pexpect.EOF:
3603 main.log.error( self.name + ": EOF exception found" )
3604 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003605 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003606 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003607 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003608 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003609
Jon Hall146f1522015-03-24 15:33:24 -07003610 def appStatus( self, appName ):
3611 """
3612 Uses the onos:apps cli command to return the status of an application.
3613 Returns:
3614 "ACTIVE" - If app is installed and activated
3615 "INSTALLED" - If app is installed and deactivated
3616 "UNINSTALLED" - If app is not installed
3617 None - on error
3618 """
Jon Hall146f1522015-03-24 15:33:24 -07003619 try:
3620 if not isinstance( appName, types.StringType ):
3621 main.log.error( self.name + ".appStatus(): appName must be" +
3622 " a string" )
3623 return None
3624 output = self.apps( jsonFormat=True )
3625 appsJson = json.loads( output )
3626 state = None
3627 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003628 if appName == app.get( 'name' ):
3629 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003630 break
3631 if state == "ACTIVE" or state == "INSTALLED":
3632 return state
3633 elif state is None:
Jon Hall8bafdc02017-09-05 11:36:26 -07003634 main.log.warn( "{} app not found", appName )
Jon Hall146f1522015-03-24 15:33:24 -07003635 return "UNINSTALLED"
3636 elif state:
3637 main.log.error( "Unexpected state from 'onos:apps': " +
3638 str( state ) )
3639 return state
Jon Hallc6793552016-01-19 14:18:37 -08003640 except ( TypeError, ValueError ):
3641 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003642 return None
3643 except pexpect.EOF:
3644 main.log.error( self.name + ": EOF exception found" )
3645 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003646 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003647 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003648 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003649 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003650
Jon Hallbe379602015-03-24 13:39:32 -07003651 def app( self, appName, option ):
3652 """
3653 Interacts with the app command for ONOS. This command manages
3654 application inventory.
3655 """
Jon Hallbe379602015-03-24 13:39:32 -07003656 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003657 # Validate argument types
3658 valid = True
3659 if not isinstance( appName, types.StringType ):
3660 main.log.error( self.name + ".app(): appName must be a " +
3661 "string" )
3662 valid = False
3663 if not isinstance( option, types.StringType ):
3664 main.log.error( self.name + ".app(): option must be a string" )
3665 valid = False
3666 if not valid:
3667 return main.FALSE
3668 # Validate Option
3669 option = option.lower()
3670 # NOTE: Install may become a valid option
3671 if option == "activate":
3672 pass
3673 elif option == "deactivate":
3674 pass
3675 elif option == "uninstall":
3676 pass
3677 else:
3678 # Invalid option
3679 main.log.error( "The ONOS app command argument only takes " +
3680 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003681 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003682 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003683 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003684 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003685 assert output is not None, "Error in sendline"
3686 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003687 if "Error executing command" in output:
3688 main.log.error( "Error in processing onos:app command: " +
3689 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003690 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003691 elif "No such application" in output:
3692 main.log.error( "The application '" + appName +
3693 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003694 return main.FALSE
3695 elif "Command not found:" in output:
3696 main.log.error( "Error in processing onos:app command: " +
3697 str( output ) )
3698 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003699 elif "Unsupported command:" in output:
3700 main.log.error( "Incorrect command given to 'app': " +
3701 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003702 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003703 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003704 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003705 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003706 except AssertionError:
3707 main.log.exception( self.name + ": AssertionError exception found" )
3708 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003709 except TypeError:
3710 main.log.exception( self.name + ": Object not as expected" )
3711 return main.ERROR
3712 except pexpect.EOF:
3713 main.log.error( self.name + ": EOF exception found" )
3714 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003715 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003716 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003717 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003718 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003719
Jon Hallbd16b922015-03-26 17:53:15 -07003720 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003721 """
3722 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003723 appName is the hierarchical app name, not the feature name
3724 If check is True, method will check the status of the app after the
3725 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003726 Returns main.TRUE if the command was successfully sent
3727 main.FALSE if the cli responded with an error or given
3728 incorrect input
3729 """
3730 try:
3731 if not isinstance( appName, types.StringType ):
3732 main.log.error( self.name + ".activateApp(): appName must be" +
3733 " a string" )
3734 return main.FALSE
3735 status = self.appStatus( appName )
3736 if status == "INSTALLED":
3737 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003738 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003739 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003740 status = self.appStatus( appName )
3741 if status == "ACTIVE":
3742 return main.TRUE
3743 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003744 main.log.debug( "The state of application " +
3745 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003746 time.sleep( 1 )
3747 return main.FALSE
3748 else: # not 'check' or command didn't succeed
3749 return response
Jon Hall146f1522015-03-24 15:33:24 -07003750 elif status == "ACTIVE":
3751 return main.TRUE
3752 elif status == "UNINSTALLED":
3753 main.log.error( self.name + ": Tried to activate the " +
3754 "application '" + appName + "' which is not " +
3755 "installed." )
3756 else:
3757 main.log.error( "Unexpected return value from appStatus: " +
3758 str( status ) )
3759 return main.ERROR
3760 except TypeError:
3761 main.log.exception( self.name + ": Object not as expected" )
3762 return main.ERROR
3763 except pexpect.EOF:
3764 main.log.error( self.name + ": EOF exception found" )
3765 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003766 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003767 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003768 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003769 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003770
Jon Hallbd16b922015-03-26 17:53:15 -07003771 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003772 """
3773 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003774 appName is the hierarchical app name, not the feature name
3775 If check is True, method will check the status of the app after the
3776 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003777 Returns main.TRUE if the command was successfully sent
3778 main.FALSE if the cli responded with an error or given
3779 incorrect input
3780 """
3781 try:
3782 if not isinstance( appName, types.StringType ):
3783 main.log.error( self.name + ".deactivateApp(): appName must " +
3784 "be a string" )
3785 return main.FALSE
3786 status = self.appStatus( appName )
3787 if status == "INSTALLED":
3788 return main.TRUE
3789 elif status == "ACTIVE":
3790 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003791 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003792 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003793 status = self.appStatus( appName )
3794 if status == "INSTALLED":
3795 return main.TRUE
3796 else:
3797 time.sleep( 1 )
3798 return main.FALSE
3799 else: # not check or command didn't succeed
3800 return response
Jon Hall146f1522015-03-24 15:33:24 -07003801 elif status == "UNINSTALLED":
3802 main.log.warn( self.name + ": Tried to deactivate the " +
3803 "application '" + appName + "' which is not " +
3804 "installed." )
3805 return main.TRUE
3806 else:
3807 main.log.error( "Unexpected return value from appStatus: " +
3808 str( status ) )
3809 return main.ERROR
3810 except TypeError:
3811 main.log.exception( self.name + ": Object not as expected" )
3812 return main.ERROR
3813 except pexpect.EOF:
3814 main.log.error( self.name + ": EOF exception found" )
3815 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003816 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003817 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003818 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003819 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003820
Jon Hallbd16b922015-03-26 17:53:15 -07003821 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003822 """
3823 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003824 appName is the hierarchical app name, not the feature name
3825 If check is True, method will check the status of the app after the
3826 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003827 Returns main.TRUE if the command was successfully sent
3828 main.FALSE if the cli responded with an error or given
3829 incorrect input
3830 """
3831 # TODO: check with Thomas about the state machine for apps
3832 try:
3833 if not isinstance( appName, types.StringType ):
3834 main.log.error( self.name + ".uninstallApp(): appName must " +
3835 "be a string" )
3836 return main.FALSE
3837 status = self.appStatus( appName )
3838 if status == "INSTALLED":
3839 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003840 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003841 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003842 status = self.appStatus( appName )
3843 if status == "UNINSTALLED":
3844 return main.TRUE
3845 else:
3846 time.sleep( 1 )
3847 return main.FALSE
3848 else: # not check or command didn't succeed
3849 return response
Jon Hall146f1522015-03-24 15:33:24 -07003850 elif status == "ACTIVE":
3851 main.log.warn( self.name + ": Tried to uninstall the " +
3852 "application '" + appName + "' which is " +
3853 "currently active." )
3854 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003855 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003856 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003857 status = self.appStatus( appName )
3858 if status == "UNINSTALLED":
3859 return main.TRUE
3860 else:
3861 time.sleep( 1 )
3862 return main.FALSE
3863 else: # not check or command didn't succeed
3864 return response
Jon Hall146f1522015-03-24 15:33:24 -07003865 elif status == "UNINSTALLED":
3866 return main.TRUE
3867 else:
3868 main.log.error( "Unexpected return value from appStatus: " +
3869 str( status ) )
3870 return main.ERROR
3871 except TypeError:
3872 main.log.exception( self.name + ": Object not as expected" )
3873 return main.ERROR
3874 except pexpect.EOF:
3875 main.log.error( self.name + ": EOF exception found" )
3876 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003877 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003878 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003879 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003880 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003881
3882 def appIDs( self, jsonFormat=True ):
3883 """
3884 Show the mappings between app id and app names given by the 'app-ids'
3885 cli command
3886 """
3887 try:
3888 cmdStr = "app-ids"
3889 if jsonFormat:
3890 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003891 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003892 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003893 assert "Command not found:" not in output, output
3894 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003895 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003896 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003897 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003898 return None
3899 except TypeError:
3900 main.log.exception( self.name + ": Object not as expected" )
3901 return None
3902 except pexpect.EOF:
3903 main.log.error( self.name + ": EOF exception found" )
3904 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003905 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003906 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003907 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003908 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003909
3910 def appToIDCheck( self ):
3911 """
3912 This method will check that each application's ID listed in 'apps' is
3913 the same as the ID listed in 'app-ids'. The check will also check that
3914 there are no duplicate IDs issued. Note that an app ID should be
3915 a globaly unique numerical identifier for app/app-like features. Once
3916 an ID is registered, the ID is never freed up so that if an app is
3917 reinstalled it will have the same ID.
3918
3919 Returns: main.TRUE if the check passes and
3920 main.FALSE if the check fails or
3921 main.ERROR if there is some error in processing the test
3922 """
3923 try:
Jon Hall390696c2015-05-05 17:13:41 -07003924 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003925 rawJson = self.appIDs( jsonFormat=True )
3926 if rawJson:
3927 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003928 else:
Jon Hallc6793552016-01-19 14:18:37 -08003929 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003930 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003931 rawJson = self.apps( jsonFormat=True )
3932 if rawJson:
3933 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003934 else:
Jon Hallc6793552016-01-19 14:18:37 -08003935 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003936 bail = True
3937 if bail:
3938 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003939 result = main.TRUE
3940 for app in apps:
3941 appID = app.get( 'id' )
3942 if appID is None:
3943 main.log.error( "Error parsing app: " + str( app ) )
3944 result = main.FALSE
3945 appName = app.get( 'name' )
3946 if appName is None:
3947 main.log.error( "Error parsing app: " + str( app ) )
3948 result = main.FALSE
3949 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003950 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07003951 if not current: # if ids doesn't have this id
3952 result = main.FALSE
3953 main.log.error( "'app-ids' does not have the ID for " +
3954 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08003955 main.log.debug( "apps command returned: " + str( app ) +
3956 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003957 elif len( current ) > 1:
3958 # there is more than one app with this ID
3959 result = main.FALSE
3960 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003961 elif not current[ 0 ][ 'name' ] == appName:
3962 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07003963 result = main.FALSE
3964 main.log.error( "'app-ids' has " + str( currentName ) +
3965 " registered under id:" + str( appID ) +
3966 " but 'apps' has " + str( appName ) )
3967 else:
3968 pass # id and name match!
3969 # now make sure that app-ids has no duplicates
3970 idsList = []
3971 namesList = []
3972 for item in ids:
3973 idsList.append( item[ 'id' ] )
3974 namesList.append( item[ 'name' ] )
3975 if len( idsList ) != len( set( idsList ) ) or\
3976 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003977 main.log.error( "'app-ids' has some duplicate entries: \n"
3978 + json.dumps( ids,
3979 sort_keys=True,
3980 indent=4,
3981 separators=( ',', ': ' ) ) )
3982 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003983 return result
Jon Hallc6793552016-01-19 14:18:37 -08003984 except ( TypeError, ValueError ):
3985 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003986 return main.ERROR
3987 except pexpect.EOF:
3988 main.log.error( self.name + ": EOF exception found" )
3989 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003990 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003991 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003992 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003993 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003994
Jon Hallfb760a02015-04-13 15:35:03 -07003995 def getCfg( self, component=None, propName=None, short=False,
3996 jsonFormat=True ):
3997 """
3998 Get configuration settings from onos cli
3999 Optional arguments:
4000 component - Optionally only list configurations for a specific
4001 component. If None, all components with configurations
4002 are displayed. Case Sensitive string.
4003 propName - If component is specified, propName option will show
4004 only this specific configuration from that component.
4005 Case Sensitive string.
4006 jsonFormat - Returns output as json. Note that this will override
4007 the short option
4008 short - Short, less verbose, version of configurations.
4009 This is overridden by the json option
4010 returns:
4011 Output from cli as a string or None on error
4012 """
4013 try:
4014 baseStr = "cfg"
4015 cmdStr = " get"
4016 componentStr = ""
4017 if component:
4018 componentStr += " " + component
4019 if propName:
4020 componentStr += " " + propName
4021 if jsonFormat:
4022 baseStr += " -j"
4023 elif short:
4024 baseStr += " -s"
4025 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004026 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004027 assert "Command not found:" not in output, output
4028 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004029 return output
4030 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004031 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004032 return None
4033 except TypeError:
4034 main.log.exception( self.name + ": Object not as expected" )
4035 return None
4036 except pexpect.EOF:
4037 main.log.error( self.name + ": EOF exception found" )
4038 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004039 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004040 except Exception:
4041 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004042 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004043
4044 def setCfg( self, component, propName, value=None, check=True ):
4045 """
4046 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004047 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004048 component - The case sensitive name of the component whose
4049 property is to be set
4050 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004051 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004052 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004053 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004054 check - Boolean, Check whether the option was successfully set this
4055 only applies when a value is given.
4056 returns:
4057 main.TRUE on success or main.FALSE on failure. If check is False,
4058 will return main.TRUE unless there is an error
4059 """
4060 try:
4061 baseStr = "cfg"
4062 cmdStr = " set " + str( component ) + " " + str( propName )
4063 if value is not None:
4064 cmdStr += " " + str( value )
4065 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004066 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004067 assert "Command not found:" not in output, output
4068 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004069 if value and check:
4070 results = self.getCfg( component=str( component ),
4071 propName=str( propName ),
4072 jsonFormat=True )
4073 # Check if current value is what we just set
4074 try:
4075 jsonOutput = json.loads( results )
4076 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004077 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004078 main.log.exception( "Error parsing cfg output" )
4079 main.log.error( "output:" + repr( results ) )
4080 return main.FALSE
4081 if current == str( value ):
4082 return main.TRUE
4083 return main.FALSE
4084 return main.TRUE
4085 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004086 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004087 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004088 except ( TypeError, ValueError ):
4089 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004090 return main.FALSE
4091 except pexpect.EOF:
4092 main.log.error( self.name + ": EOF exception found" )
4093 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004094 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004095 except Exception:
4096 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004097 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004098
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004099 def distPrimitivesSend( self, cmd ):
4100 """
4101 Function to handle sending cli commands for the distributed primitives test app
4102
4103 This command will catch some exceptions and retry the command on some
4104 specific store exceptions.
4105
4106 Required arguments:
4107 cmd - The command to send to the cli
4108 returns:
4109 string containing the cli output
4110 None on Error
4111 """
4112 try:
4113 output = self.sendline( cmd )
4114 try:
4115 assert output is not None, "Error in sendline"
4116 # TODO: Maybe make this less hardcoded
4117 # ConsistentMap Exceptions
4118 assert "org.onosproject.store.service" not in output
4119 # Node not leader
4120 assert "java.lang.IllegalStateException" not in output
4121 except AssertionError:
4122 main.log.error( "Error in processing '" + cmd + "' " +
4123 "command: " + str( output ) )
4124 retryTime = 30 # Conservative time, given by Madan
4125 main.log.info( "Waiting " + str( retryTime ) +
4126 "seconds before retrying." )
4127 time.sleep( retryTime ) # Due to change in mastership
4128 output = self.sendline( cmd )
4129 assert output is not None, "Error in sendline"
4130 assert "Command not found:" not in output, output
4131 assert "Error executing command" not in output, output
4132 main.log.info( self.name + ": " + output )
4133 return output
4134 except AssertionError:
4135 main.log.exception( "Error in processing '" + cmd + "' command." )
4136 return None
4137 except TypeError:
4138 main.log.exception( self.name + ": Object not as expected" )
4139 return None
4140 except pexpect.EOF:
4141 main.log.error( self.name + ": EOF exception found" )
4142 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004143 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004144 except Exception:
4145 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004146 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004147
Jon Hall390696c2015-05-05 17:13:41 -07004148 def setTestAdd( self, setName, values ):
4149 """
4150 CLI command to add elements to a distributed set.
4151 Arguments:
4152 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004153 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004154 Example usages:
4155 setTestAdd( "set1", "a b c" )
4156 setTestAdd( "set2", "1" )
4157 returns:
4158 main.TRUE on success OR
4159 main.FALSE if elements were already in the set OR
4160 main.ERROR on error
4161 """
4162 try:
4163 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004164 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004165 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4166 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004167 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004168 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004169 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004170 return main.FALSE
4171 else:
4172 main.log.error( self.name + ": setTestAdd did not" +
4173 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004174 main.log.debug( self.name + " actual: " + repr( output ) )
4175 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004176 except TypeError:
4177 main.log.exception( self.name + ": Object not as expected" )
4178 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004179 except Exception:
4180 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004181 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004182
4183 def setTestRemove( self, setName, values, clear=False, retain=False ):
4184 """
4185 CLI command to remove elements from a distributed set.
4186 Required arguments:
4187 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004188 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004189 Optional arguments:
4190 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004191 retain - Retain only the given values. (intersection of the
4192 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004193 returns:
4194 main.TRUE on success OR
4195 main.FALSE if the set was not changed OR
4196 main.ERROR on error
4197 """
4198 try:
4199 cmdStr = "set-test-remove "
4200 if clear:
4201 cmdStr += "-c " + str( setName )
4202 elif retain:
4203 cmdStr += "-r " + str( setName ) + " " + str( values )
4204 else:
4205 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004206 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004207 if clear:
4208 pattern = "Set " + str( setName ) + " cleared"
4209 if re.search( pattern, output ):
4210 return main.TRUE
4211 elif retain:
4212 positivePattern = str( setName ) + " was pruned to contain " +\
4213 "only elements of set \[(.*)\]"
4214 negativePattern = str( setName ) + " was not changed by " +\
4215 "retaining only elements of the set " +\
4216 "\[(.*)\]"
4217 if re.search( positivePattern, output ):
4218 return main.TRUE
4219 elif re.search( negativePattern, output ):
4220 return main.FALSE
4221 else:
4222 positivePattern = "\[(.*)\] was removed from the set " +\
4223 str( setName )
4224 if ( len( values.split() ) == 1 ):
4225 negativePattern = "\[(.*)\] was not in set " +\
4226 str( setName )
4227 else:
4228 negativePattern = "No element of \[(.*)\] was in set " +\
4229 str( setName )
4230 if re.search( positivePattern, output ):
4231 return main.TRUE
4232 elif re.search( negativePattern, output ):
4233 return main.FALSE
4234 main.log.error( self.name + ": setTestRemove did not" +
4235 " match expected output" )
4236 main.log.debug( self.name + " expected: " + pattern )
4237 main.log.debug( self.name + " actual: " + repr( output ) )
4238 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004239 except TypeError:
4240 main.log.exception( self.name + ": Object not as expected" )
4241 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004242 except Exception:
4243 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004244 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004245
4246 def setTestGet( self, setName, values="" ):
4247 """
4248 CLI command to get the elements in a distributed set.
4249 Required arguments:
4250 setName - The name of the set to remove from.
4251 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004252 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004253 returns:
4254 main.ERROR on error OR
4255 A list of elements in the set if no optional arguments are
4256 supplied OR
4257 A tuple containing the list then:
4258 main.FALSE if the given values are not in the set OR
4259 main.TRUE if the given values are in the set OR
4260 """
4261 try:
4262 values = str( values ).strip()
4263 setName = str( setName ).strip()
4264 length = len( values.split() )
4265 containsCheck = None
4266 # Patterns to match
4267 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004268 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004269 containsTrue = "Set " + setName + " contains the value " + values
4270 containsFalse = "Set " + setName + " did not contain the value " +\
4271 values
4272 containsAllTrue = "Set " + setName + " contains the the subset " +\
4273 setPattern
4274 containsAllFalse = "Set " + setName + " did not contain the the" +\
4275 " subset " + setPattern
4276
4277 cmdStr = "set-test-get "
4278 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004279 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004280 if length == 0:
4281 match = re.search( pattern, output )
4282 else: # if given values
4283 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004284 patternTrue = pattern + "\r\n" + containsTrue
4285 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004286 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004287 patternTrue = pattern + "\r\n" + containsAllTrue
4288 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004289 matchTrue = re.search( patternTrue, output )
4290 matchFalse = re.search( patternFalse, output )
4291 if matchTrue:
4292 containsCheck = main.TRUE
4293 match = matchTrue
4294 elif matchFalse:
4295 containsCheck = main.FALSE
4296 match = matchFalse
4297 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004298 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004299 "expected output" )
4300 main.log.debug( self.name + " expected: " + pattern )
4301 main.log.debug( self.name + " actual: " + repr( output ) )
4302 match = None
4303 if match:
4304 setMatch = match.group( 1 )
4305 if setMatch == '':
4306 setList = []
4307 else:
4308 setList = setMatch.split( ", " )
4309 if length > 0:
4310 return ( setList, containsCheck )
4311 else:
4312 return setList
4313 else: # no match
4314 main.log.error( self.name + ": setTestGet did not" +
4315 " match expected output" )
4316 main.log.debug( self.name + " expected: " + pattern )
4317 main.log.debug( self.name + " actual: " + repr( output ) )
4318 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004319 except TypeError:
4320 main.log.exception( self.name + ": Object not as expected" )
4321 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004322 except Exception:
4323 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004324 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004325
4326 def setTestSize( self, setName ):
4327 """
4328 CLI command to get the elements in a distributed set.
4329 Required arguments:
4330 setName - The name of the set to remove from.
4331 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004332 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004333 None on error
4334 """
4335 try:
4336 # TODO: Should this check against the number of elements returned
4337 # and then return true/false based on that?
4338 setName = str( setName ).strip()
4339 # Patterns to match
4340 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004341 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004342 setPattern
4343 cmdStr = "set-test-get -s "
4344 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004345 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004346 match = re.search( pattern, output )
4347 if match:
4348 setSize = int( match.group( 1 ) )
4349 setMatch = match.group( 2 )
4350 if len( setMatch.split() ) == setSize:
4351 main.log.info( "The size returned by " + self.name +
4352 " matches the number of elements in " +
4353 "the returned set" )
4354 else:
4355 main.log.error( "The size returned by " + self.name +
4356 " does not match the number of " +
4357 "elements in the returned set." )
4358 return setSize
4359 else: # no match
4360 main.log.error( self.name + ": setTestGet 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 None
Jon Hall390696c2015-05-05 17:13:41 -07004365 except TypeError:
4366 main.log.exception( self.name + ": Object not as expected" )
4367 return None
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
Jon Hall80daded2015-05-27 16:07:00 -07004372 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004373 """
4374 Command to list the various counters in the system.
4375 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004376 if jsonFormat, a string of the json object returned by the cli
4377 command
4378 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004379 None on error
4380 """
Jon Hall390696c2015-05-05 17:13:41 -07004381 try:
Jon Hall390696c2015-05-05 17:13:41 -07004382 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004383 if jsonFormat:
4384 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004385 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004386 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004387 assert "Command not found:" not in output, output
4388 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004389 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004390 return output
Jon Hall390696c2015-05-05 17:13:41 -07004391 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004392 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004393 return None
Jon Hall390696c2015-05-05 17:13:41 -07004394 except TypeError:
4395 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004396 return None
Jon Hall390696c2015-05-05 17:13:41 -07004397 except pexpect.EOF:
4398 main.log.error( self.name + ": EOF exception found" )
4399 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004400 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004401 except Exception:
4402 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004403 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004404
Jon Hall935db192016-04-19 00:22:04 -07004405 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004406 """
Jon Halle1a3b752015-07-22 13:02:46 -07004407 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004408 Required arguments:
4409 counter - The name of the counter to increment.
4410 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004411 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004412 returns:
4413 integer value of the counter or
4414 None on Error
4415 """
4416 try:
4417 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004418 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004419 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004420 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004421 if delta != 1:
4422 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004423 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004424 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004425 match = re.search( pattern, output )
4426 if match:
4427 return int( match.group( 1 ) )
4428 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004429 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004430 " match expected output." )
4431 main.log.debug( self.name + " expected: " + pattern )
4432 main.log.debug( self.name + " actual: " + repr( output ) )
4433 return None
Jon Hall390696c2015-05-05 17:13:41 -07004434 except TypeError:
4435 main.log.exception( self.name + ": Object not as expected" )
4436 return None
Jon Hall390696c2015-05-05 17:13:41 -07004437 except Exception:
4438 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004439 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004440
Jon Hall935db192016-04-19 00:22:04 -07004441 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004442 """
4443 CLI command to get a distributed counter then add a delta to it.
4444 Required arguments:
4445 counter - The name of the counter to increment.
4446 Optional arguments:
4447 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004448 returns:
4449 integer value of the counter or
4450 None on Error
4451 """
4452 try:
4453 counter = str( counter )
4454 delta = int( delta )
4455 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004456 cmdStr += counter
4457 if delta != 1:
4458 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004459 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004460 pattern = counter + " was updated to (-?\d+)"
4461 match = re.search( pattern, output )
4462 if match:
4463 return int( match.group( 1 ) )
4464 else:
4465 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4466 " match expected output." )
4467 main.log.debug( self.name + " expected: " + pattern )
4468 main.log.debug( self.name + " actual: " + repr( output ) )
4469 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004470 except TypeError:
4471 main.log.exception( self.name + ": Object not as expected" )
4472 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004473 except Exception:
4474 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004475 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004476
4477 def valueTestGet( self, valueName ):
4478 """
4479 CLI command to get the value of an atomic value.
4480 Required arguments:
4481 valueName - The name of the value to get.
4482 returns:
4483 string value of the value or
4484 None on Error
4485 """
4486 try:
4487 valueName = str( valueName )
4488 cmdStr = "value-test "
4489 operation = "get"
4490 cmdStr = "value-test {} {}".format( valueName,
4491 operation )
4492 output = self.distPrimitivesSend( cmdStr )
4493 pattern = "(\w+)"
4494 match = re.search( pattern, output )
4495 if match:
4496 return match.group( 1 )
4497 else:
4498 main.log.error( self.name + ": valueTestGet did not" +
4499 " match expected output." )
4500 main.log.debug( self.name + " expected: " + pattern )
4501 main.log.debug( self.name + " actual: " + repr( output ) )
4502 return None
4503 except TypeError:
4504 main.log.exception( self.name + ": Object not as expected" )
4505 return None
4506 except Exception:
4507 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004508 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004509
4510 def valueTestSet( self, valueName, newValue ):
4511 """
4512 CLI command to set the value of an atomic value.
4513 Required arguments:
4514 valueName - The name of the value to set.
4515 newValue - The value to assign to the given value.
4516 returns:
4517 main.TRUE on success or
4518 main.ERROR on Error
4519 """
4520 try:
4521 valueName = str( valueName )
4522 newValue = str( newValue )
4523 operation = "set"
4524 cmdStr = "value-test {} {} {}".format( valueName,
4525 operation,
4526 newValue )
4527 output = self.distPrimitivesSend( cmdStr )
4528 if output is not None:
4529 return main.TRUE
4530 else:
4531 return main.ERROR
4532 except TypeError:
4533 main.log.exception( self.name + ": Object not as expected" )
4534 return main.ERROR
4535 except Exception:
4536 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004537 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004538
4539 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4540 """
4541 CLI command to compareAndSet the value of an atomic value.
4542 Required arguments:
4543 valueName - The name of the value.
4544 oldValue - Compare the current value of the atomic value to this
4545 newValue - If the value equals oldValue, set the value to newValue
4546 returns:
4547 main.TRUE on success or
4548 main.FALSE on failure or
4549 main.ERROR on Error
4550 """
4551 try:
4552 valueName = str( valueName )
4553 oldValue = str( oldValue )
4554 newValue = str( newValue )
4555 operation = "compareAndSet"
4556 cmdStr = "value-test {} {} {} {}".format( valueName,
4557 operation,
4558 oldValue,
4559 newValue )
4560 output = self.distPrimitivesSend( cmdStr )
4561 pattern = "(\w+)"
4562 match = re.search( pattern, output )
4563 if match:
4564 result = match.group( 1 )
4565 if result == "true":
4566 return main.TRUE
4567 elif result == "false":
4568 return main.FALSE
4569 else:
4570 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4571 " match expected output." )
4572 main.log.debug( self.name + " expected: " + pattern )
4573 main.log.debug( self.name + " actual: " + repr( output ) )
4574 return main.ERROR
4575 except TypeError:
4576 main.log.exception( self.name + ": Object not as expected" )
4577 return main.ERROR
4578 except Exception:
4579 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004580 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004581
4582 def valueTestGetAndSet( self, valueName, newValue ):
4583 """
4584 CLI command to getAndSet the value of an atomic value.
4585 Required arguments:
4586 valueName - The name of the value to get.
4587 newValue - The value to assign to the given value
4588 returns:
4589 string value of the value or
4590 None on Error
4591 """
4592 try:
4593 valueName = str( valueName )
4594 cmdStr = "value-test "
4595 operation = "getAndSet"
4596 cmdStr += valueName + " " + operation
4597 cmdStr = "value-test {} {} {}".format( valueName,
4598 operation,
4599 newValue )
4600 output = self.distPrimitivesSend( cmdStr )
4601 pattern = "(\w+)"
4602 match = re.search( pattern, output )
4603 if match:
4604 return match.group( 1 )
4605 else:
4606 main.log.error( self.name + ": valueTestGetAndSet did not" +
4607 " match expected output." )
4608 main.log.debug( self.name + " expected: " + pattern )
4609 main.log.debug( self.name + " actual: " + repr( output ) )
4610 return None
4611 except TypeError:
4612 main.log.exception( self.name + ": Object not as expected" )
4613 return None
4614 except Exception:
4615 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004616 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004617
4618 def valueTestDestroy( self, valueName ):
4619 """
4620 CLI command to destroy an atomic value.
4621 Required arguments:
4622 valueName - The name of the value to destroy.
4623 returns:
4624 main.TRUE on success or
4625 main.ERROR on Error
4626 """
4627 try:
4628 valueName = str( valueName )
4629 cmdStr = "value-test "
4630 operation = "destroy"
4631 cmdStr += valueName + " " + operation
4632 output = self.distPrimitivesSend( cmdStr )
4633 if output is not None:
4634 return main.TRUE
4635 else:
4636 return main.ERROR
4637 except TypeError:
4638 main.log.exception( self.name + ": Object not as expected" )
4639 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004640 except Exception:
4641 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004642 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004643
YPZhangfebf7302016-05-24 16:45:56 -07004644 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004645 """
4646 Description: Execute summary command in onos
4647 Returns: json object ( summary -j ), returns main.FALSE if there is
4648 no output
4649
4650 """
4651 try:
4652 cmdStr = "summary"
4653 if jsonFormat:
4654 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004655 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004656 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004657 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004658 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004659 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004660 if not handle:
4661 main.log.error( self.name + ": There is no output in " +
4662 "summary command" )
4663 return main.FALSE
4664 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004665 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004666 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004667 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004668 except TypeError:
4669 main.log.exception( self.name + ": Object not as expected" )
4670 return None
4671 except pexpect.EOF:
4672 main.log.error( self.name + ": EOF exception found" )
4673 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004674 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004675 except Exception:
4676 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004677 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004678
Jon Hall935db192016-04-19 00:22:04 -07004679 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004680 """
4681 CLI command to get the value of a key in a consistent map using
4682 transactions. This a test function and can only get keys from the
4683 test map hard coded into the cli command
4684 Required arguments:
4685 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004686 returns:
4687 The string value of the key or
4688 None on Error
4689 """
4690 try:
4691 keyName = str( keyName )
4692 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004693 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004694 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004695 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4696 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004697 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004698 return None
4699 else:
4700 match = re.search( pattern, output )
4701 if match:
4702 return match.groupdict()[ 'value' ]
4703 else:
4704 main.log.error( self.name + ": transactionlMapGet did not" +
4705 " match expected output." )
4706 main.log.debug( self.name + " expected: " + pattern )
4707 main.log.debug( self.name + " actual: " + repr( output ) )
4708 return None
4709 except TypeError:
4710 main.log.exception( self.name + ": Object not as expected" )
4711 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004712 except Exception:
4713 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004714 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004715
Jon Hall935db192016-04-19 00:22:04 -07004716 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004717 """
4718 CLI command to put a value into 'numKeys' number of keys in a
4719 consistent map using transactions. This a test function and can only
4720 put into keys named 'Key#' of the test map hard coded into the cli command
4721 Required arguments:
4722 numKeys - Number of keys to add the value to
4723 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004724 returns:
4725 A dictionary whose keys are the name of the keys put into the map
4726 and the values of the keys are dictionaries whose key-values are
4727 'value': value put into map and optionaly
4728 'oldValue': Previous value in the key or
4729 None on Error
4730
4731 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004732 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4733 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004734 """
4735 try:
4736 numKeys = str( numKeys )
4737 value = str( value )
4738 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004739 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004740 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004741 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4742 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4743 results = {}
4744 for line in output.splitlines():
4745 new = re.search( newPattern, line )
4746 updated = re.search( updatedPattern, line )
4747 if new:
4748 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4749 elif updated:
4750 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004751 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004752 else:
4753 main.log.error( self.name + ": transactionlMapGet did not" +
4754 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004755 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4756 newPattern,
4757 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004758 main.log.debug( self.name + " actual: " + repr( output ) )
4759 return results
4760 except TypeError:
4761 main.log.exception( self.name + ": Object not as expected" )
4762 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004763 except Exception:
4764 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004765 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004766
acsmarsdaea66c2015-09-03 11:44:06 -07004767 def maps( self, jsonFormat=True ):
4768 """
4769 Description: Returns result of onos:maps
4770 Optional:
4771 * jsonFormat: enable json formatting of output
4772 """
4773 try:
4774 cmdStr = "maps"
4775 if jsonFormat:
4776 cmdStr += " -j"
4777 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004778 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004779 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004780 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004781 except AssertionError:
4782 main.log.exception( "" )
4783 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004784 except TypeError:
4785 main.log.exception( self.name + ": Object not as expected" )
4786 return None
4787 except pexpect.EOF:
4788 main.log.error( self.name + ": EOF exception found" )
4789 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004790 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004791 except Exception:
4792 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004793 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004794
4795 def getSwController( self, uri, jsonFormat=True ):
4796 """
4797 Descrition: Gets the controller information from the device
4798 """
4799 try:
4800 cmd = "device-controllers "
4801 if jsonFormat:
4802 cmd += "-j "
4803 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004804 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004805 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004806 return response
Jon Hallc6793552016-01-19 14:18:37 -08004807 except AssertionError:
4808 main.log.exception( "" )
4809 return None
GlennRC050596c2015-11-18 17:06:41 -08004810 except TypeError:
4811 main.log.exception( self.name + ": Object not as expected" )
4812 return None
4813 except pexpect.EOF:
4814 main.log.error( self.name + ": EOF exception found" )
4815 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004816 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004817 except Exception:
4818 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004819 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004820
4821 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4822 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004823 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004824
4825 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004826 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08004827 ip - String or List: The ip address of the controller.
4828 This parameter can be formed in a couple of different ways.
4829 VALID:
4830 10.0.0.1 - just the ip address
4831 tcp:10.0.0.1 - the protocol and the ip address
4832 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4833 so that you can add controllers with different
4834 protocols and ports
4835 INVALID:
4836 10.0.0.1:6653 - this is not supported by ONOS
4837
4838 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4839 port - The port number.
4840 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4841
4842 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4843 """
4844 try:
4845 cmd = "device-setcontrollers"
4846
4847 if jsonFormat:
4848 cmd += " -j"
4849 cmd += " " + uri
4850 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004851 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08004852 for item in ip:
4853 if ":" in item:
4854 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004855 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08004856 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004857 elif "." in sitem[ 1 ]:
4858 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08004859 else:
4860 main.log.error( "Malformed entry: " + item )
4861 raise TypeError
4862 else:
4863 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004864 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004865 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004866 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004867 if "Error" in response:
4868 main.log.error( response )
4869 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004870 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004871 except AssertionError:
4872 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004873 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004874 except TypeError:
4875 main.log.exception( self.name + ": Object not as expected" )
4876 return main.FALSE
4877 except pexpect.EOF:
4878 main.log.error( self.name + ": EOF exception found" )
4879 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004880 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004881 except Exception:
4882 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004883 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004884
4885 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004886 '''
GlennRC20fc6522015-12-23 23:26:57 -08004887 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004888 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08004889 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004890 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08004891 Returns:
4892 Returns main.FALSE if an exception is thrown or an error is present
4893 in the response. Otherwise, returns main.TRUE.
4894 NOTE:
4895 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004896 '''
GlennRC20fc6522015-12-23 23:26:57 -08004897 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004898 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07004899 deviceStr = device
4900 device = []
4901 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004902
4903 for d in device:
4904 time.sleep( 1 )
4905 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004906 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004907 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004908 if "Error" in response:
4909 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4910 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004911 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004912 except AssertionError:
4913 main.log.exception( "" )
4914 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004915 except TypeError:
4916 main.log.exception( self.name + ": Object not as expected" )
4917 return main.FALSE
4918 except pexpect.EOF:
4919 main.log.error( self.name + ": EOF exception found" )
4920 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004921 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004922 except Exception:
4923 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004924 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004925
4926 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004927 '''
GlennRC20fc6522015-12-23 23:26:57 -08004928 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004929 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08004930 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004931 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08004932 Returns:
4933 Returns main.FALSE if an exception is thrown or an error is present
4934 in the response. Otherwise, returns main.TRUE.
4935 NOTE:
4936 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004937 '''
GlennRC20fc6522015-12-23 23:26:57 -08004938 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004939 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08004940 host = list( host )
4941
4942 for h in host:
4943 time.sleep( 1 )
4944 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004945 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004946 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004947 if "Error" in response:
4948 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4949 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004950 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004951 except AssertionError:
4952 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004953 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004954 except TypeError:
4955 main.log.exception( self.name + ": Object not as expected" )
4956 return main.FALSE
4957 except pexpect.EOF:
4958 main.log.error( self.name + ": EOF exception found" )
4959 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004960 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004961 except Exception:
4962 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004963 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004964
YPZhangfebf7302016-05-24 16:45:56 -07004965 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004966 '''
GlennRCed771242016-01-13 17:02:47 -08004967 Description:
4968 Bring link down or up in the null-provider.
4969 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004970 begin - (string) One end of a device or switch.
4971 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08004972 returns:
4973 main.TRUE if no exceptions were thrown and no Errors are
4974 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004975 '''
GlennRCed771242016-01-13 17:02:47 -08004976 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004977 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004978 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004979 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004980 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004981 if "Error" in response or "Failure" in response:
4982 main.log.error( response )
4983 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004984 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004985 except AssertionError:
4986 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004987 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004988 except TypeError:
4989 main.log.exception( self.name + ": Object not as expected" )
4990 return main.FALSE
4991 except pexpect.EOF:
4992 main.log.error( self.name + ": EOF exception found" )
4993 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004994 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004995 except Exception:
4996 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004997 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004998
Jon Hall2c8959e2016-12-16 12:17:34 -08004999 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005000 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005001 Description:
5002 Changes the state of port in an OF switch by means of the
5003 PORTSTATUS OF messages.
5004 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005005 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5006 port - (string) target port in the device. Ex: '2'
5007 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005008 returns:
5009 main.TRUE if no exceptions were thrown and no Errors are
5010 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005011 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005012 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005013 state = state.lower()
5014 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005015 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005016 response = self.sendline( cmd, showResponse=True )
5017 assert response is not None, "Error in sendline"
5018 assert "Command not found:" not in response, response
5019 if "Error" in response or "Failure" in response:
5020 main.log.error( response )
5021 return main.FALSE
5022 return main.TRUE
5023 except AssertionError:
5024 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005025 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005026 except TypeError:
5027 main.log.exception( self.name + ": Object not as expected" )
5028 return main.FALSE
5029 except pexpect.EOF:
5030 main.log.error( self.name + ": EOF exception found" )
5031 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005032 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005033 except Exception:
5034 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005035 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005036
5037 def logSet( self, level="INFO", app="org.onosproject" ):
5038 """
5039 Set the logging level to lvl for a specific app
5040 returns main.TRUE on success
5041 returns main.FALSE if Error occurred
5042 if noExit is True, TestON will not exit, but clean up
5043 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5044 Level defaults to INFO
5045 """
5046 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005047 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005048 self.handle.expect( "onos>" )
5049
5050 response = self.handle.before
5051 if re.search( "Error", response ):
5052 return main.FALSE
5053 return main.TRUE
5054 except pexpect.TIMEOUT:
5055 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005056 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005057 except pexpect.EOF:
5058 main.log.error( self.name + ": EOF exception found" )
5059 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005060 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005061 except Exception:
5062 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005063 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005064
5065 def getGraphDict( self, timeout=60, includeHost=False ):
5066 """
5067 Return a dictionary which describes the latest network topology data as a
5068 graph.
5069 An example of the dictionary:
5070 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5071 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5072 Each vertex should at least have an 'edges' attribute which describes the
5073 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005074 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005075 list of attributes.
5076 An example of the edges dictionary:
5077 'edges': { vertex2: { 'port': ..., 'weight': ... },
5078 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005079 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005080 in topology data.
5081 """
5082 graphDict = {}
5083 try:
5084 links = self.links()
5085 links = json.loads( links )
5086 devices = self.devices()
5087 devices = json.loads( devices )
5088 idToDevice = {}
5089 for device in devices:
5090 idToDevice[ device[ 'id' ] ] = device
5091 if includeHost:
5092 hosts = self.hosts()
5093 # FIXME: support 'includeHost' argument
5094 for link in links:
5095 nodeA = link[ 'src' ][ 'device' ]
5096 nodeB = link[ 'dst' ][ 'device' ]
5097 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005098 if nodeA not in graphDict.keys():
5099 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005100 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005101 'type': idToDevice[ nodeA ][ 'type' ],
5102 'available': idToDevice[ nodeA ][ 'available' ],
5103 'role': idToDevice[ nodeA ][ 'role' ],
5104 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5105 'hw': idToDevice[ nodeA ][ 'hw' ],
5106 'sw': idToDevice[ nodeA ][ 'sw' ],
5107 'serial': idToDevice[ nodeA ][ 'serial' ],
5108 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005109 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005110 else:
5111 # Assert nodeB is not connected to any current links of nodeA
5112 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005113 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5114 'type': link[ 'type' ],
5115 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005116 return graphDict
5117 except ( TypeError, ValueError ):
5118 main.log.exception( self.name + ": Object not as expected" )
5119 return None
5120 except KeyError:
5121 main.log.exception( self.name + ": KeyError exception found" )
5122 return None
5123 except AssertionError:
5124 main.log.exception( self.name + ": AssertionError exception found" )
5125 return None
5126 except pexpect.EOF:
5127 main.log.error( self.name + ": EOF exception found" )
5128 main.log.error( self.name + ": " + self.handle.before )
5129 return None
5130 except Exception:
5131 main.log.exception( self.name + ": Uncaught exception!" )
5132 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005133
5134 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005135 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005136 Send command to check intent-perf summary
5137 Returns: dictionary for intent-perf summary
5138 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005139 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005140 cmd = "intent-perf -s"
5141 respDic = {}
5142 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005143 assert resp is not None, "Error in sendline"
5144 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005145 try:
5146 # Generate the dictionary to return
5147 for l in resp.split( "\n" ):
5148 # Delete any white space in line
5149 temp = re.sub( r'\s+', '', l )
5150 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005151 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005152
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005153 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005154 main.log.exception( self.name + ": Object not as expected" )
5155 return None
5156 except KeyError:
5157 main.log.exception( self.name + ": KeyError exception found" )
5158 return None
5159 except AssertionError:
5160 main.log.exception( self.name + ": AssertionError exception found" )
5161 return None
5162 except pexpect.EOF:
5163 main.log.error( self.name + ": EOF exception found" )
5164 main.log.error( self.name + ": " + self.handle.before )
5165 return None
5166 except Exception:
5167 main.log.exception( self.name + ": Uncaught exception!" )
5168 return None
5169 return respDic
5170
Chiyu Chengec63bde2016-11-17 18:11:36 -08005171 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005172 """
5173 Searches the latest ONOS log file for the given search term and
5174 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005175
chengchiyu08303a02016-09-08 17:40:26 -07005176 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005177 searchTerm:
5178 The string to grep from the ONOS log.
5179 startLine:
5180 The term that decides which line is the start to search the searchTerm in
5181 the karaf log. For now, startTerm only works in 'first' mode.
5182 logNum:
5183 In some extreme cases, one karaf log is not big enough to contain all the
5184 information.Because of this, search mutiply logs is necessary to capture
5185 the right result. logNum is the number of karaf logs that we need to search
5186 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005187 mode:
5188 all: return all the strings that contain the search term
5189 last: return the last string that contains the search term
5190 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005191 num: return the number of times that the searchTerm appears in the log
5192 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005193 """
5194 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005195 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005196 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005197 logPath = '/opt/onos/log/karaf.log.'
5198 logPaths = '/opt/onos/log/karaf.log'
5199 for i in range( 1, logNum ):
5200 logPaths = logPath + str( i ) + " " + logPaths
5201 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005202 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005203 # 100000000 is just a extreme large number to make sure this function can
5204 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005205 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005206 if mode == 'all':
5207 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005208 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005209 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005210 elif mode == 'first':
5211 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5212 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005213 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005214 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005215 return num
You Wang6d301d42017-04-21 10:49:33 -07005216 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005217 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005218 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005219 else:
5220 main.log.error( self.name + " unsupported mode" )
5221 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005222 before = self.sendline( cmd )
5223 before = before.splitlines()
5224 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005225 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005226 return returnLines
5227 except AssertionError:
5228 main.log.error( self.name + " searchTerm is not string type" )
5229 return None
5230 except pexpect.EOF:
5231 main.log.error( self.name + ": EOF exception found" )
5232 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005233 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005234 except pexpect.TIMEOUT:
5235 main.log.error( self.name + ": TIMEOUT exception found" )
5236 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005237 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005238 except Exception:
5239 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005240 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005241
5242 def vplsShow( self, jsonFormat=True ):
5243 """
5244 Description: Returns result of onos:vpls show, which should list the
5245 configured VPLS networks and the assigned interfaces.
5246 Optional:
5247 * jsonFormat: enable json formatting of output
5248 Returns:
5249 The output of the command or None on error.
5250 """
5251 try:
5252 cmdStr = "vpls show"
5253 if jsonFormat:
5254 raise NotImplementedError
5255 cmdStr += " -j"
5256 handle = self.sendline( cmdStr )
5257 assert handle is not None, "Error in sendline"
5258 assert "Command not found:" not in handle, handle
5259 return handle
5260 except AssertionError:
5261 main.log.exception( "" )
5262 return None
5263 except TypeError:
5264 main.log.exception( self.name + ": Object not as expected" )
5265 return None
5266 except pexpect.EOF:
5267 main.log.error( self.name + ": EOF exception found" )
5268 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005269 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005270 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005271 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005272 return None
5273 except Exception:
5274 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005275 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005276
5277 def parseVplsShow( self ):
5278 """
5279 Parse the cli output of 'vpls show' into json output. This is required
5280 as there is currently no json output available.
5281 """
5282 try:
5283 output = []
5284 raw = self.vplsShow( jsonFormat=False )
5285 namePat = "VPLS name: (?P<name>\w+)"
5286 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5287 encapPat = "Encapsulation: (?P<encap>\w+)"
5288 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5289 mIter = re.finditer( pattern, raw )
5290 for match in mIter:
5291 item = {}
5292 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005293 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005294 if ifaces == [ "" ]:
5295 ifaces = []
5296 item[ 'interfaces' ] = ifaces
5297 encap = match.group( 'encap' )
5298 if encap != 'NONE':
5299 item[ 'encapsulation' ] = encap.lower()
5300 output.append( item )
5301 return output
5302 except Exception:
5303 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005304 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005305
5306 def vplsList( self, jsonFormat=True ):
5307 """
5308 Description: Returns result of onos:vpls list, which should list the
5309 configured VPLS networks.
5310 Optional:
5311 * jsonFormat: enable json formatting of output
5312 """
5313 try:
5314 cmdStr = "vpls list"
5315 if jsonFormat:
5316 raise NotImplementedError
5317 cmdStr += " -j"
5318 handle = self.sendline( cmdStr )
5319 assert handle is not None, "Error in sendline"
5320 assert "Command not found:" not in handle, handle
5321 return handle
5322 except AssertionError:
5323 main.log.exception( "" )
5324 return None
5325 except TypeError:
5326 main.log.exception( self.name + ": Object not as expected" )
5327 return None
5328 except pexpect.EOF:
5329 main.log.error( self.name + ": EOF exception found" )
5330 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005331 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005332 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005333 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005334 return None
5335 except Exception:
5336 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005337 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005338
5339 def vplsCreate( self, network ):
5340 """
5341 CLI command to create a new VPLS network.
5342 Required arguments:
5343 network - String name of the network to create.
5344 returns:
5345 main.TRUE on success and main.FALSE on failure
5346 """
5347 try:
5348 network = str( network )
5349 cmdStr = "vpls create "
5350 cmdStr += network
5351 output = self.sendline( cmdStr )
5352 assert output is not None, "Error in sendline"
5353 assert "Command not found:" not in output, output
5354 assert "Error executing command" not in output, output
5355 assert "VPLS already exists:" not in output, output
5356 return main.TRUE
5357 except AssertionError:
5358 main.log.exception( "" )
5359 return main.FALSE
5360 except TypeError:
5361 main.log.exception( self.name + ": Object not as expected" )
5362 return main.FALSE
5363 except pexpect.EOF:
5364 main.log.error( self.name + ": EOF exception found" )
5365 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005366 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005367 except Exception:
5368 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005369 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005370
5371 def vplsDelete( self, network ):
5372 """
5373 CLI command to delete a VPLS network.
5374 Required arguments:
5375 network - Name of the network to delete.
5376 returns:
5377 main.TRUE on success and main.FALSE on failure
5378 """
5379 try:
5380 network = str( network )
5381 cmdStr = "vpls delete "
5382 cmdStr += network
5383 output = self.sendline( cmdStr )
5384 assert output is not None, "Error in sendline"
5385 assert "Command not found:" not in output, output
5386 assert "Error executing command" not in output, output
5387 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005388 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005389 return main.TRUE
5390 except AssertionError:
5391 main.log.exception( "" )
5392 return main.FALSE
5393 except TypeError:
5394 main.log.exception( self.name + ": Object not as expected" )
5395 return main.FALSE
5396 except pexpect.EOF:
5397 main.log.error( self.name + ": EOF exception found" )
5398 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005399 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005400 except Exception:
5401 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005402 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005403
5404 def vplsAddIface( self, network, iface ):
5405 """
5406 CLI command to add an interface to a VPLS network.
5407 Required arguments:
5408 network - Name of the network to add the interface to.
5409 iface - The ONOS name for an interface.
5410 returns:
5411 main.TRUE on success and main.FALSE on failure
5412 """
5413 try:
5414 network = str( network )
5415 iface = str( iface )
5416 cmdStr = "vpls add-if "
5417 cmdStr += network + " " + iface
5418 output = self.sendline( cmdStr )
5419 assert output is not None, "Error in sendline"
5420 assert "Command not found:" not in output, output
5421 assert "Error executing command" not in output, output
5422 assert "already associated to network" not in output, output
5423 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005424 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005425 return main.TRUE
5426 except AssertionError:
5427 main.log.exception( "" )
5428 return main.FALSE
5429 except TypeError:
5430 main.log.exception( self.name + ": Object not as expected" )
5431 return main.FALSE
5432 except pexpect.EOF:
5433 main.log.error( self.name + ": EOF exception found" )
5434 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005435 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005436 except Exception:
5437 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005438 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005439
5440 def vplsRemIface( self, network, iface ):
5441 """
5442 CLI command to remove an interface from a VPLS network.
5443 Required arguments:
5444 network - Name of the network to remove the interface from.
5445 iface - Name of the interface to remove.
5446 returns:
5447 main.TRUE on success and main.FALSE on failure
5448 """
5449 try:
5450 iface = str( iface )
5451 cmdStr = "vpls rem-if "
5452 cmdStr += network + " " + iface
5453 output = self.sendline( cmdStr )
5454 assert output is not None, "Error in sendline"
5455 assert "Command not found:" not in output, output
5456 assert "Error executing command" not in output, output
5457 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005458 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005459 return main.TRUE
5460 except AssertionError:
5461 main.log.exception( "" )
5462 return main.FALSE
5463 except TypeError:
5464 main.log.exception( self.name + ": Object not as expected" )
5465 return main.FALSE
5466 except pexpect.EOF:
5467 main.log.error( self.name + ": EOF exception found" )
5468 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005469 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005470 except Exception:
5471 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005472 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005473
5474 def vplsClean( self ):
5475 """
5476 Description: Clears the VPLS app configuration.
5477 Returns: main.TRUE on success and main.FALSE on failure
5478 """
5479 try:
5480 cmdStr = "vpls clean"
5481 handle = self.sendline( cmdStr )
5482 assert handle is not None, "Error in sendline"
5483 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005484 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005485 return handle
5486 except AssertionError:
5487 main.log.exception( "" )
5488 return main.FALSE
5489 except TypeError:
5490 main.log.exception( self.name + ": Object not as expected" )
5491 return main.FALSE
5492 except pexpect.EOF:
5493 main.log.error( self.name + ": EOF exception found" )
5494 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005495 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005496 except Exception:
5497 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005498 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005499
5500 def vplsSetEncap( self, network, encapType ):
5501 """
5502 CLI command to add an interface to a VPLS network.
5503 Required arguments:
5504 network - Name of the network to create.
5505 encapType - Type of encapsulation.
5506 returns:
5507 main.TRUE on success and main.FALSE on failure
5508 """
5509 try:
5510 network = str( network )
5511 encapType = str( encapType ).upper()
5512 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5513 cmdStr = "vpls set-encap "
5514 cmdStr += network + " " + encapType
5515 output = self.sendline( cmdStr )
5516 assert output is not None, "Error in sendline"
5517 assert "Command not found:" not in output, output
5518 assert "Error executing command" not in output, output
5519 assert "already associated to network" not in output, output
5520 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005521 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005522 return main.TRUE
5523 except AssertionError:
5524 main.log.exception( "" )
5525 return main.FALSE
5526 except TypeError:
5527 main.log.exception( self.name + ": Object not as expected" )
5528 return main.FALSE
5529 except pexpect.EOF:
5530 main.log.error( self.name + ": EOF exception found" )
5531 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005532 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005533 except Exception:
5534 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005535 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005536
5537 def interfaces( self, jsonFormat=True ):
5538 """
5539 Description: Returns result of interfaces command.
5540 Optional:
5541 * jsonFormat: enable json formatting of output
5542 Returns:
5543 The output of the command or None on error.
5544 """
5545 try:
5546 cmdStr = "interfaces"
5547 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005548 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005549 cmdStr += " -j"
5550 handle = self.sendline( cmdStr )
5551 assert handle is not None, "Error in sendline"
5552 assert "Command not found:" not in handle, handle
5553 return handle
5554 except AssertionError:
5555 main.log.exception( "" )
5556 return None
5557 except TypeError:
5558 main.log.exception( self.name + ": Object not as expected" )
5559 return None
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 NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005565 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005566 return None
5567 except Exception:
5568 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005569 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005570
5571 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005572 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005573 Get the timestamp of searchTerm from karaf log.
5574
5575 Arguments:
5576 splitTerm_before and splitTerm_after:
5577
5578 The terms that split the string that contains the timeStamp of
5579 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5580 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5581 and the splitTerm_after is "x"
5582
5583 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005584 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005585 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005586 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005587 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005588 return main.ERROR
5589 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005590 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005591 main.log.warn( "Captured timestamp string is empty" )
5592 return main.ERROR
5593 lines = lines[ 0 ]
5594 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005595 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005596 # get the target value
5597 line = lines.split( splitTerm_before )
5598 key = line[ 1 ].split( splitTerm_after )
5599 return int( key[ 0 ] )
5600 except IndexError:
5601 main.log.warn( "Index Error!" )
5602 return main.ERROR
5603 except AssertionError:
5604 main.log.warn( "Search Term Not Found " )
5605 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005606
5607 def workQueueAdd( self, queueName, value ):
5608 """
5609 CLI command to add a string to the specified Work Queue.
5610 This function uses the distributed primitives test app, which
5611 gives some cli access to distributed primitives for testing
5612 purposes only.
5613
5614 Required arguments:
5615 queueName - The name of the queue to add to
5616 value - The value to add to the queue
5617 returns:
5618 main.TRUE on success, main.FALSE on failure and
5619 main.ERROR on error.
5620 """
5621 try:
5622 queueName = str( queueName )
5623 value = str( value )
5624 prefix = "work-queue-test"
5625 operation = "add"
5626 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5627 output = self.distPrimitivesSend( cmdStr )
5628 if "Invalid operation name" in output:
5629 main.log.warn( output )
5630 return main.ERROR
5631 elif "Done" in output:
5632 return main.TRUE
5633 except TypeError:
5634 main.log.exception( self.name + ": Object not as expected" )
5635 return main.ERROR
5636 except Exception:
5637 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005638 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005639
5640 def workQueueAddMultiple( self, queueName, value1, value2 ):
5641 """
5642 CLI command to add two strings to the specified Work Queue.
5643 This function uses the distributed primitives test app, which
5644 gives some cli access to distributed primitives for testing
5645 purposes only.
5646
5647 Required arguments:
5648 queueName - The name of the queue to add to
5649 value1 - The first value to add to the queue
5650 value2 - The second value to add to the queue
5651 returns:
5652 main.TRUE on success, main.FALSE on failure and
5653 main.ERROR on error.
5654 """
5655 try:
5656 queueName = str( queueName )
5657 value1 = str( value1 )
5658 value2 = str( value2 )
5659 prefix = "work-queue-test"
5660 operation = "addMultiple"
5661 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5662 output = self.distPrimitivesSend( cmdStr )
5663 if "Invalid operation name" in output:
5664 main.log.warn( output )
5665 return main.ERROR
5666 elif "Done" in output:
5667 return main.TRUE
5668 except TypeError:
5669 main.log.exception( self.name + ": Object not as expected" )
5670 return main.ERROR
5671 except Exception:
5672 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005673 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005674
5675 def workQueueTakeAndComplete( self, queueName, number=1 ):
5676 """
5677 CLI command to take a value from the specified Work Queue and compelte it.
5678 This function uses the distributed primitives test app, which
5679 gives some cli access to distributed primitives for testing
5680 purposes only.
5681
5682 Required arguments:
5683 queueName - The name of the queue to add to
5684 number - The number of items to take and complete
5685 returns:
5686 main.TRUE on success, main.FALSE on failure and
5687 main.ERROR on error.
5688 """
5689 try:
5690 queueName = str( queueName )
5691 number = str( int( number ) )
5692 prefix = "work-queue-test"
5693 operation = "takeAndComplete"
5694 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5695 output = self.distPrimitivesSend( cmdStr )
5696 if "Invalid operation name" in output:
5697 main.log.warn( output )
5698 return main.ERROR
5699 elif "Done" in output:
5700 return main.TRUE
5701 except TypeError:
5702 main.log.exception( self.name + ": Object not as expected" )
5703 return main.ERROR
5704 except Exception:
5705 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005706 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005707
5708 def workQueueDestroy( self, queueName ):
5709 """
5710 CLI command to destroy the specified Work Queue.
5711 This function uses the distributed primitives test app, which
5712 gives some cli access to distributed primitives for testing
5713 purposes only.
5714
5715 Required arguments:
5716 queueName - The name of the queue to add to
5717 returns:
5718 main.TRUE on success, main.FALSE on failure and
5719 main.ERROR on error.
5720 """
5721 try:
5722 queueName = str( queueName )
5723 prefix = "work-queue-test"
5724 operation = "destroy"
5725 cmdStr = " ".join( [ prefix, queueName, operation ] )
5726 output = self.distPrimitivesSend( cmdStr )
5727 if "Invalid operation name" in output:
5728 main.log.warn( output )
5729 return main.ERROR
5730 return main.TRUE
5731 except TypeError:
5732 main.log.exception( self.name + ": Object not as expected" )
5733 return main.ERROR
5734 except Exception:
5735 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005736 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005737
5738 def workQueueTotalPending( self, queueName ):
5739 """
5740 CLI command to get the Total Pending items of the specified Work Queue.
5741 This function uses the distributed primitives test app, which
5742 gives some cli access to distributed primitives for testing
5743 purposes only.
5744
5745 Required arguments:
5746 queueName - The name of the queue to add to
5747 returns:
5748 The number of Pending items in the specified work queue or
5749 None on error
5750 """
5751 try:
5752 queueName = str( queueName )
5753 prefix = "work-queue-test"
5754 operation = "totalPending"
5755 cmdStr = " ".join( [ prefix, queueName, operation ] )
5756 output = self.distPrimitivesSend( cmdStr )
5757 pattern = r'\d+'
5758 if "Invalid operation name" in output:
5759 main.log.warn( output )
5760 return None
5761 else:
5762 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005763 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005764 except ( AttributeError, TypeError ):
5765 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5766 return None
5767 except Exception:
5768 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005769 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005770
5771 def workQueueTotalCompleted( self, queueName ):
5772 """
5773 CLI command to get the Total Completed items of the specified Work Queue.
5774 This function uses the distributed primitives test app, which
5775 gives some cli access to distributed primitives for testing
5776 purposes only.
5777
5778 Required arguments:
5779 queueName - The name of the queue to add to
5780 returns:
5781 The number of complete items in the specified work queue or
5782 None on error
5783 """
5784 try:
5785 queueName = str( queueName )
5786 prefix = "work-queue-test"
5787 operation = "totalCompleted"
5788 cmdStr = " ".join( [ prefix, queueName, operation ] )
5789 output = self.distPrimitivesSend( cmdStr )
5790 pattern = r'\d+'
5791 if "Invalid operation name" in output:
5792 main.log.warn( output )
5793 return None
5794 else:
5795 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005796 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005797 except ( AttributeError, TypeError ):
5798 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5799 return None
5800 except Exception:
5801 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005802 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005803
5804 def workQueueTotalInProgress( self, queueName ):
5805 """
5806 CLI command to get the Total In Progress items of the specified Work Queue.
5807 This function uses the distributed primitives test app, which
5808 gives some cli access to distributed primitives for testing
5809 purposes only.
5810
5811 Required arguments:
5812 queueName - The name of the queue to add to
5813 returns:
5814 The number of In Progress items in the specified work queue or
5815 None on error
5816 """
5817 try:
5818 queueName = str( queueName )
5819 prefix = "work-queue-test"
5820 operation = "totalInProgress"
5821 cmdStr = " ".join( [ prefix, queueName, operation ] )
5822 output = self.distPrimitivesSend( cmdStr )
5823 pattern = r'\d+'
5824 if "Invalid operation name" in output:
5825 main.log.warn( output )
5826 return None
5827 else:
5828 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005829 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005830 except ( AttributeError, TypeError ):
5831 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5832 return None
5833 except Exception:
5834 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005835 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005836
5837 def events( self, args='-a' ):
5838 """
5839 Description: Returns events -a command output
5840 Optional:
5841 add other arguments
5842 """
5843 try:
5844 cmdStr = "events"
5845 if args:
5846 cmdStr += " " + args
5847 handle = self.sendline( cmdStr )
5848 assert handle is not None, "Error in sendline"
5849 assert "Command not found:" not in handle, handle
5850 return handle
5851 except AssertionError:
5852 main.log.exception( "" )
5853 return None
5854 except TypeError:
5855 main.log.exception( self.name + ": Object not as expected" )
5856 return None
5857 except pexpect.EOF:
5858 main.log.error( self.name + ": EOF exception found" )
5859 main.log.error( self.name + ": " + self.handle.before )
5860 main.cleanAndExit()
5861 except Exception:
5862 main.log.exception( self.name + ": Uncaught exception!" )
5863 main.cleanAndExit()
5864
5865 def getMaster( self, deviceID ):
5866 """
5867 Description: Obtains current master using "roles" command for a specific deviceID
5868 """
5869 try:
5870 return str( self.getRole( deviceID )[ 'master' ] )
5871 except AssertionError:
5872 main.log.exception( "" )
5873 return None
5874 except TypeError:
5875 main.log.exception( self.name + ": Object not as expected" )
5876 return None
5877 except pexpect.EOF:
5878 main.log.error( self.name + ": EOF exception found" )
5879 main.log.error( self.name + ": " + self.handle.before )
5880 main.cleanAndExit()
5881 except Exception:
5882 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07005883 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08005884
5885 def issu( self ):
5886 """
5887 Short summary of In-Service Software Upgrade status
5888
5889 Returns the output of the cli command or None on Error
5890 """
5891 try:
5892 cmdStr = "issu"
5893 handle = self.sendline( cmdStr )
5894 assert handle is not None, "Error in sendline"
5895 assert "Command not found:" not in handle, handle
5896 assert "Unsupported command:" not in handle, handle
5897 return handle
5898 except AssertionError:
5899 main.log.exception( "" )
5900 return None
5901 except TypeError:
5902 main.log.exception( self.name + ": Object not as expected" )
5903 return None
5904 except pexpect.EOF:
5905 main.log.error( self.name + ": EOF exception found" )
5906 main.log.error( self.name + ": " + self.handle.before )
5907 main.cleanAndExit()
5908 except Exception:
5909 main.log.exception( self.name + ": Uncaught exception!" )
5910 main.cleanAndExit()
5911
5912 def issuInit( self ):
5913 """
5914 Initiates an In-Service Software Upgrade
5915
5916 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5917 """
5918 try:
5919 cmdStr = "issu init"
5920 handle = self.sendline( cmdStr )
5921 assert handle is not None, "Error in sendline"
5922 assert "Command not found:" not in handle, handle
5923 assert "Unsupported command:" not in handle, handle
5924 if "Initialized" in handle:
5925 return main.TRUE
5926 else:
5927 return main.FALSE
5928 except AssertionError:
5929 main.log.exception( "" )
5930 return main.ERROR
5931 except TypeError:
5932 main.log.exception( self.name + ": Object not as expected" )
5933 return main.ERROR
5934 except pexpect.EOF:
5935 main.log.error( self.name + ": EOF exception found" )
5936 main.log.error( self.name + ": " + self.handle.before )
5937 main.cleanAndExit()
5938 except Exception:
5939 main.log.exception( self.name + ": Uncaught exception!" )
5940 main.cleanAndExit()
5941
5942 def issuUpgrade( self ):
5943 """
5944 Transitions stores to upgraded nodes
5945
5946 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5947 """
5948 try:
5949 cmdStr = "issu upgrade"
5950 handle = self.sendline( cmdStr )
5951 assert handle is not None, "Error in sendline"
5952 assert "Command not found:" not in handle, handle
5953 assert "Unsupported command:" not in handle, handle
5954 if "Upgraded" in handle:
5955 return main.TRUE
5956 else:
5957 return main.FALSE
5958 except AssertionError:
5959 main.log.exception( "" )
5960 return main.ERROR
5961 except TypeError:
5962 main.log.exception( self.name + ": Object not as expected" )
5963 return main.ERROR
5964 except pexpect.EOF:
5965 main.log.error( self.name + ": EOF exception found" )
5966 main.log.error( self.name + ": " + self.handle.before )
5967 main.cleanAndExit()
5968 except Exception:
5969 main.log.exception( self.name + ": Uncaught exception!" )
5970 main.cleanAndExit()
5971
5972 def issuCommit( self ):
5973 """
5974 Finalizes an In-Service Software Upgrade
5975
5976 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5977 """
5978 try:
5979 cmdStr = "issu commit"
5980 handle = self.sendline( cmdStr )
5981 assert handle is not None, "Error in sendline"
5982 assert "Command not found:" not in handle, handle
5983 assert "Unsupported command:" not in handle, handle
5984 # TODO: Check the version returned by this command
5985 if "Committed version" in handle:
5986 return main.TRUE
5987 else:
5988 return main.FALSE
5989 except AssertionError:
5990 main.log.exception( "" )
5991 return main.ERROR
5992 except TypeError:
5993 main.log.exception( self.name + ": Object not as expected" )
5994 return main.ERROR
5995 except pexpect.EOF:
5996 main.log.error( self.name + ": EOF exception found" )
5997 main.log.error( self.name + ": " + self.handle.before )
5998 main.cleanAndExit()
5999 except Exception:
6000 main.log.exception( self.name + ": Uncaught exception!" )
6001 main.cleanAndExit()
6002
6003 def issuRollback( self ):
6004 """
6005 Rolls back an In-Service Software Upgrade
6006
6007 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6008 """
6009 try:
6010 cmdStr = "issu rollback"
6011 handle = self.sendline( cmdStr )
6012 assert handle is not None, "Error in sendline"
6013 assert "Command not found:" not in handle, handle
6014 assert "Unsupported command:" not in handle, handle
6015 # TODO: Check the version returned by this command
6016 if "Rolled back to version" in handle:
6017 return main.TRUE
6018 else:
6019 return main.FALSE
6020 except AssertionError:
6021 main.log.exception( "" )
6022 return main.ERROR
6023 except TypeError:
6024 main.log.exception( self.name + ": Object not as expected" )
6025 return main.ERROR
6026 except pexpect.EOF:
6027 main.log.error( self.name + ": EOF exception found" )
6028 main.log.error( self.name + ": " + self.handle.before )
6029 main.cleanAndExit()
6030 except Exception:
6031 main.log.exception( self.name + ": Uncaught exception!" )
6032 main.cleanAndExit()
6033
6034 def issuReset( self ):
6035 """
6036 Resets the In-Service Software Upgrade status after a rollback
6037
6038 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6039 """
6040 try:
6041 cmdStr = "issu reset"
6042 handle = self.sendline( cmdStr )
6043 assert handle is not None, "Error in sendline"
6044 assert "Command not found:" not in handle, handle
6045 assert "Unsupported command:" not in handle, handle
6046 # TODO: Check the version returned by this command
6047 if "Reset version" in handle:
6048 return main.TRUE
6049 else:
6050 return main.FALSE
6051 except AssertionError:
6052 main.log.exception( "" )
6053 return main.ERROR
6054 except TypeError:
6055 main.log.exception( self.name + ": Object not as expected" )
6056 return main.ERROR
6057 except pexpect.EOF:
6058 main.log.error( self.name + ": EOF exception found" )
6059 main.log.error( self.name + ": " + self.handle.before )
6060 main.cleanAndExit()
6061 except Exception:
6062 main.log.exception( self.name + ": Uncaught exception!" )
6063 main.cleanAndExit()
6064
6065 def issuStatus( self ):
6066 """
6067 Status of an In-Service Software Upgrade
6068
6069 Returns the output of the cli command or None on Error
6070 """
6071 try:
6072 cmdStr = "issu status"
6073 handle = self.sendline( cmdStr )
6074 assert handle is not None, "Error in sendline"
6075 assert "Command not found:" not in handle, handle
6076 assert "Unsupported command:" not in handle, handle
6077 return handle
6078 except AssertionError:
6079 main.log.exception( "" )
6080 return None
6081 except TypeError:
6082 main.log.exception( self.name + ": Object not as expected" )
6083 return None
6084 except pexpect.EOF:
6085 main.log.error( self.name + ": EOF exception found" )
6086 main.log.error( self.name + ": " + self.handle.before )
6087 main.cleanAndExit()
6088 except Exception:
6089 main.log.exception( self.name + ": Uncaught exception!" )
6090 main.cleanAndExit()
6091
6092 def issuVersion( self ):
6093 """
6094 Get the version of an In-Service Software Upgrade
6095
6096 Returns the output of the cli command or None on Error
6097 """
6098 try:
6099 cmdStr = "issu version"
6100 handle = self.sendline( cmdStr )
6101 assert handle is not None, "Error in sendline"
6102 assert "Command not found:" not in handle, handle
6103 assert "Unsupported command:" not in handle, handle
6104 return handle
6105 except AssertionError:
6106 main.log.exception( "" )
6107 return None
6108 except TypeError:
6109 main.log.exception( self.name + ": Object not as expected" )
6110 return None
6111 except pexpect.EOF:
6112 main.log.error( self.name + ": EOF exception found" )
6113 main.log.error( self.name + ": " + self.handle.before )
6114 main.cleanAndExit()
6115 except Exception:
6116 main.log.exception( self.name + ": Uncaught exception!" )
6117 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006118
6119 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6120 """
6121 Create a multicast route by calling 'mcast-join' command
6122 sIP: source IP of the multicast route
6123 groupIP: group IP of the multicast route
6124 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6125 dPorts: a list of destination ports of the multicast route
6126 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6127 """
6128 try:
6129 cmdStr = "mcast-join"
6130 cmdStr += " " + str( sIP )
6131 cmdStr += " " + str( groupIP )
6132 cmdStr += " " + str( sPort )
6133 assert isinstance( dPorts, list )
6134 for dPort in dPorts:
6135 cmdStr += " " + str( dPort )
6136 handle = self.sendline( cmdStr )
6137 assert handle is not None, "Error in sendline"
6138 assert "Command not found:" not in handle, handle
6139 assert "Unsupported command:" not in handle, handle
6140 assert "Error executing command" not in handle, handle
6141 if "Added the mcast route" in handle:
6142 return main.TRUE
6143 else:
6144 return main.FALSE
6145 except AssertionError:
6146 main.log.exception( "" )
6147 return None
6148 except TypeError:
6149 main.log.exception( self.name + ": Object not as expected" )
6150 return None
6151 except pexpect.EOF:
6152 main.log.error( self.name + ": EOF exception found" )
6153 main.log.error( self.name + ": " + self.handle.before )
6154 main.cleanAndExit()
6155 except Exception:
6156 main.log.exception( self.name + ": Uncaught exception!" )
6157 main.cleanAndExit()
6158
6159 def mcastDelete( self, sIP, groupIP, dPorts ):
6160 """
6161 Delete a multicast route by calling 'mcast-delete' command
6162 sIP: source IP of the multicast route
6163 groupIP: group IP of the multicast route
6164 dPorts: a list of destination ports of the multicast route
6165 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6166 """
6167 try:
6168 cmdStr = "mcast-delete"
6169 cmdStr += " " + str( sIP )
6170 cmdStr += " " + str( groupIP )
6171 assert isinstance( dPorts, list )
6172 for dPort in dPorts:
6173 cmdStr += " " + str( dPort )
6174 handle = self.sendline( cmdStr )
6175 assert handle is not None, "Error in sendline"
6176 assert "Command not found:" not in handle, handle
6177 assert "Unsupported command:" not in handle, handle
6178 assert "Error executing command" not in handle, handle
6179 if "Updated the mcast route" in handle:
6180 return main.TRUE
6181 else:
6182 return main.FALSE
6183 except AssertionError:
6184 main.log.exception( "" )
6185 return None
6186 except TypeError:
6187 main.log.exception( self.name + ": Object not as expected" )
6188 return None
6189 except pexpect.EOF:
6190 main.log.error( self.name + ": EOF exception found" )
6191 main.log.error( self.name + ": " + self.handle.before )
6192 main.cleanAndExit()
6193 except Exception:
6194 main.log.exception( self.name + ": Uncaught exception!" )
6195 main.cleanAndExit()
6196
6197 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6198 """
6199 Create a multicast route by calling 'mcast-host-join' command
6200 sAddr: we can provide * for ASM or a specific address for SSM
6201 gAddr: specifies multicast group address
6202 srcs: a list of the source connect points e.g. ["of:0000000000000003/12"]
6203 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6204 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6205 """
6206 try:
6207 cmdStr = "mcast-host-join"
6208 cmdStr += " -sAddr " + str( sAddr )
6209 cmdStr += " -gAddr " + str( gAddr )
6210 assert isinstance( srcs, list )
6211 for src in srcs:
6212 cmdStr += " -srcs " + str( src )
6213 assert isinstance( sinks, list )
6214 for sink in sinks:
6215 cmdStr += " -sinks " + str( sink )
6216 handle = self.sendline( cmdStr )
6217 assert handle is not None, "Error in sendline"
6218 assert "Command not found:" not in handle, handle
6219 assert "Unsupported command:" not in handle, handle
6220 assert "Error executing command" not in handle, handle
6221 if "Added the mcast route" in handle:
6222 return main.TRUE
6223 else:
6224 return main.FALSE
6225 except AssertionError:
6226 main.log.exception( "" )
6227 return None
6228 except TypeError:
6229 main.log.exception( self.name + ": Object not as expected" )
6230 return None
6231 except pexpect.EOF:
6232 main.log.error( self.name + ": EOF exception found" )
6233 main.log.error( self.name + ": " + self.handle.before )
6234 main.cleanAndExit()
6235 except Exception:
6236 main.log.exception( self.name + ": Uncaught exception!" )
6237 main.cleanAndExit()
6238
6239 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6240 """
6241 Delete multicast sink(s) by calling 'mcast-host-delete' command
6242 sAddr: we can provide * for ASM or a specific address for SSM
6243 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006244 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006245 will delete the route if not specified
6246 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6247 """
6248 try:
6249 cmdStr = "mcast-host-delete"
6250 cmdStr += " -sAddr " + str( sAddr )
6251 cmdStr += " -gAddr " + str( gAddr )
6252 if host:
6253 cmdStr += " -h " + str( host )
6254 handle = self.sendline( cmdStr )
6255 assert handle is not None, "Error in sendline"
6256 assert "Command not found:" not in handle, handle
6257 assert "Unsupported command:" not in handle, handle
6258 assert "Error executing command" not in handle, handle
6259 if "Updated the mcast route" in handle:
6260 return main.TRUE
6261 elif "Deleted the mcast route" in handle:
6262 return main.TRUE
6263 else:
6264 return main.FALSE
6265 except AssertionError:
6266 main.log.exception( "" )
6267 return None
6268 except TypeError:
6269 main.log.exception( self.name + ": Object not as expected" )
6270 return None
6271 except pexpect.EOF:
6272 main.log.error( self.name + ": EOF exception found" )
6273 main.log.error( self.name + ": " + self.handle.before )
6274 main.cleanAndExit()
6275 except Exception:
6276 main.log.exception( self.name + ": Uncaught exception!" )
6277 main.cleanAndExit()
6278
6279 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6280 """
6281 Delete multicast src(s) by calling 'mcast-source-delete' command
6282 sAddr: we can provide * for ASM or a specific address for SSM
6283 gAddr: specifies multicast group address
6284 srcs: a list of connect points of the sources e.g. ["00:AA:00:00:01:05/40"],
6285 will delete the route if not specified
6286 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6287 """
6288 try:
6289 cmdStr = "mcast-source-delete"
6290 cmdStr += " -sAddr " + str( sAddr )
6291 cmdStr += " -gAddr " + str( gAddr )
6292 if srcs:
6293 assert isinstance( srcs, list )
6294 for src in srcs:
6295 cmdStr += " -src " + str( src )
6296 handle = self.sendline( cmdStr )
6297 assert handle is not None, "Error in sendline"
6298 assert "Command not found:" not in handle, handle
6299 assert "Unsupported command:" not in handle, handle
6300 assert "Error executing command" not in handle, handle
6301 if "Updated the mcast route" in handle:
6302 return main.TRUE
6303 elif "Deleted the mcast route" in handle:
6304 return main.TRUE
6305 else:
6306 return main.FALSE
6307 except AssertionError:
6308 main.log.exception( "" )
6309 return None
6310 except TypeError:
6311 main.log.exception( self.name + ": Object not as expected" )
6312 return None
6313 except pexpect.EOF:
6314 main.log.error( self.name + ": EOF exception found" )
6315 main.log.error( self.name + ": " + self.handle.before )
6316 main.cleanAndExit()
6317 except Exception:
6318 main.log.exception( self.name + ": Uncaught exception!" )
6319 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006320
6321 def netcfg( self, jsonFormat=True, args="" ):
6322 """
6323 Run netcfg cli command with given args
6324 """
6325 try:
6326 cmdStr = "netcfg"
6327 if jsonFormat:
6328 cmdStr = cmdStr + " -j"
6329 if args:
6330 cmdStr = cmdStr + " " + str( args )
6331 handle = self.sendline( cmdStr )
6332 assert handle is not None, "Error in sendline"
6333 assert "Command not found:" not in handle, handle
6334 assert "Unsupported command:" not in handle, handle
6335 assert "Error executing command" not in handle, handle
6336 return handle
6337 except AssertionError:
6338 main.log.exception( "" )
6339 return None
6340 except TypeError:
6341 main.log.exception( self.name + ": Object not as expected" )
6342 return None
6343 except pexpect.EOF:
6344 main.log.error( self.name + ": EOF exception found" )
6345 main.log.error( self.name + ": " + self.handle.before )
6346 main.cleanAndExit()
6347 except Exception:
6348 main.log.exception( self.name + ": Uncaught exception!" )
6349 main.cleanAndExit()
6350
6351 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True ):
6352 """
6353 Compose and return t3-troubleshoot cli command for given source and destination addresses
6354 Options:
6355 sAddr: IP address of the source host
6356 dAddr: IP address of the destination host
6357 """
6358 try:
6359 # Collect information of both hosts from onos
6360 hosts = self.hosts()
6361 hosts = json.loads( hosts )
6362 sHost = None
6363 dHost = None
6364 for host in hosts:
6365 if sAddr in host[ "ipAddresses" ]:
6366 sHost = host
6367 elif dAddr in host[ "ipAddresses" ]:
6368 dHost = host
6369 if sHost and dHost:
6370 break
6371 assert sHost, "Not able to find host with IP {}".format( sAddr )
6372 assert dHost, "Not able to find host with IP {}".format( dAddr )
6373 cmdStr = "t3-troubleshoot"
6374 if verbose:
6375 cmdStr += " -vv"
6376 cmdStr += " -s " + str( sAddr )
6377 # TODO: collect t3 for all locations of source host?
6378 cmdStr += " -sp " + str( sHost[ "locations" ][ 0 ][ "elementId" ] ) + "/" + str( sHost[ "locations" ][ 0 ][ "port" ] )
6379 cmdStr += " -sm " + str( sHost[ "mac" ] )
6380 cmdStr += " -d " + str( dAddr )
6381 netcfg = self.netcfg( args="devices {}".format( sHost[ "locations" ][ 0 ][ "elementId" ] ) )
6382 netcfg = json.loads( netcfg )
6383 assert netcfg, "Failed to get netcfg"
6384 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6385 if ipv6:
6386 cmdStr += " -et ipv6"
6387 return cmdStr
6388 except AssertionError:
6389 main.log.exception( "" )
6390 return None
6391 except ( KeyError, TypeError ):
6392 main.log.exception( self.name + ": Object not as expected" )
6393 return None
6394 except Exception:
6395 main.log.exception( self.name + ": Uncaught exception!" )
6396 main.cleanAndExit()
6397
6398 def t3( self, sAddr, dAddr, ipv6=False ):
6399 """
6400 Run t3-troubleshoot cli command for given source and destination addresses
6401 Options:
6402 sAddr: IP address of the source host
6403 dAddr: IP address of the destination host
6404 """
6405 try:
6406 cmdStr = self.composeT3Command( sAddr, dAddr, ipv6 )
6407 handle = self.sendline( cmdStr )
6408 assert handle is not None, "Error in sendline"
6409 assert "Command not found:" not in handle, handle
6410 assert "Unsupported command:" not in handle, handle
6411 assert "Error executing command" not in handle, handle
6412 assert "Tracing packet" in handle
6413 return handle
6414 except AssertionError:
6415 main.log.exception( "" )
6416 return None
6417 except pexpect.EOF:
6418 main.log.error( self.name + ": EOF exception found" )
6419 main.log.error( self.name + ": " + self.handle.before )
6420 main.cleanAndExit()
6421 except Exception:
6422 main.log.exception( self.name + ": Uncaught exception!" )
6423 main.cleanAndExit()