blob: 09aa7a48b4242b2876b95f109046cf1f7cd00cf5 [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
Jon Hall9677ed32018-04-24 11:16:23 -07002889 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002890 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
2891
2892 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002893 """
2894 Description:
2895 Check whether the number of flow rules for the given device id that
2896 are in ADDED state is bigger than minFlowCount.
2897 Required:
2898 * deviceId: device id to check the number of added flow rules
2899 Optional:
2900 * minFlowCount: the number of flow rules to compare
2901 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002902 * comparison: if 0, compare with greater than minFlowCount
2903 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002904 Return:
2905 Returns the number of flow rules if it is bigger than minFlowCount,
2906 returns main.FALSE otherwise.
2907 """
2908 count = self.flowAddedCount( deviceId, core )
2909 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07002910 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002911 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002912
kelvin-onlabd3b64892015-01-20 13:26:24 -08002913 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002914 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002915 Use 'devices' function to obtain list of all devices
2916 and parse the result to obtain a list of all device
2917 id's. Returns this list. Returns empty list if no
2918 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002919 List is ordered sequentially
2920
andrewonlab3e15ead2014-10-15 14:21:34 -04002921 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002922 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002923 the ids. By obtaining the list of device ids on the fly,
2924 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002925 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002926 try:
kelvin8ec71442015-01-15 16:57:00 -08002927 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002928 devicesStr = self.devices( jsonFormat=False )
2929 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002930
kelvin-onlabd3b64892015-01-20 13:26:24 -08002931 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002932 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002933 return idList
kelvin8ec71442015-01-15 16:57:00 -08002934
2935 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002936 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002937 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002938 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002939 # Split list further into arguments before and after string
2940 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002941 # append to idList
2942 for arg in tempList:
2943 idList.append( arg.split( "id=" )[ 1 ] )
2944 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002945
Jon Halld4d4b372015-01-28 16:02:41 -08002946 except TypeError:
2947 main.log.exception( self.name + ": Object not as expected" )
2948 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002949 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002950 main.log.error( self.name + ": EOF exception found" )
2951 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002952 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002953 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002954 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002955 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002956
kelvin-onlabd3b64892015-01-20 13:26:24 -08002957 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002958 """
andrewonlab7c211572014-10-15 16:45:20 -04002959 Uses 'nodes' function to obtain list of all nodes
2960 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002961 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002962 Returns:
2963 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002964 """
andrewonlab7c211572014-10-15 16:45:20 -04002965 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002966 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002967 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002968 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002969 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002970 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002971 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002972 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002973 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002974 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002975 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002976 except ( TypeError, ValueError ):
2977 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002978 return None
andrewonlab7c211572014-10-15 16:45:20 -04002979 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002980 main.log.error( self.name + ": EOF exception found" )
2981 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002982 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002983 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002984 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002985 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002986
kelvin-onlabd3b64892015-01-20 13:26:24 -08002987 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002988 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002989 Return the first device from the devices api whose 'id' contains 'dpid'
2990 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002991 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002992 try:
kelvin8ec71442015-01-15 16:57:00 -08002993 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002994 return None
2995 else:
kelvin8ec71442015-01-15 16:57:00 -08002996 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002997 rawDevices = self.devices()
2998 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002999 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003000 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003001 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3002 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003003 return device
3004 return None
Jon Hallc6793552016-01-19 14:18:37 -08003005 except ( TypeError, ValueError ):
3006 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003007 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003008 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003009 main.log.error( self.name + ": EOF exception found" )
3010 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003011 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003012 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003013 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003014 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003015
You Wang24139872016-05-03 11:48:47 -07003016 def getTopology( self, topologyOutput ):
3017 """
3018 Definition:
3019 Loads a json topology output
3020 Return:
3021 topology = current ONOS topology
3022 """
3023 import json
3024 try:
3025 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003026 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003027 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003028 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003029 except ( TypeError, ValueError ):
3030 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3031 return None
You Wang24139872016-05-03 11:48:47 -07003032 except pexpect.EOF:
3033 main.log.error( self.name + ": EOF exception found" )
3034 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003035 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003036 except Exception:
3037 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003038 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003039
Pier6a0c4de2018-03-18 16:01:30 -07003040 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003041 """
Jon Hallefbd9792015-03-05 16:11:36 -08003042 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003043 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003044 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003045
Flavio Castro82ee2f62016-06-07 15:04:12 -07003046 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003047 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003048 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003049 logLevel = level to log to.
3050 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003051
Jon Hallefbd9792015-03-05 16:11:36 -08003052 Returns: main.TRUE if the number of switches and links are correct,
3053 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003054 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003055 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003056 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003057 try:
You Wang13310252016-07-31 10:56:14 -07003058 summary = self.summary()
3059 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003060 except ( TypeError, ValueError ):
3061 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3062 return main.ERROR
3063 try:
3064 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003065 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003066 return main.ERROR
3067 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003068 # Is the number of switches is what we expected
3069 devices = topology.get( 'devices', False )
3070 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003071 nodes = summary.get( 'nodes', False )
3072 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003073 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003074 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003075 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003076 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003077 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3078 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003079 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003080 output = output + "The number of links and switches match "\
3081 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003082 result = main.TRUE
3083 else:
You Wang24139872016-05-03 11:48:47 -07003084 output = output + \
3085 "The number of links and switches does not match " + \
3086 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003087 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003088 output = output + "\n ONOS sees %i devices" % int( devices )
3089 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003090 if int( numolink ) > 0:
3091 output = output + "and %i links " % int( links )
3092 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003093 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003094 output = output + "and %i controllers " % int( nodes )
3095 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003096 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003097 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003098 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003099 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003100 else:
You Wang24139872016-05-03 11:48:47 -07003101 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003102 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003103 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003104 main.log.error( self.name + ": EOF exception found" )
3105 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003106 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003107 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003108 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003109 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003110
kelvin-onlabd3b64892015-01-20 13:26:24 -08003111 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003112 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003113 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003114 deviceId must be the id of a device as seen in the onos devices command
3115 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003116 role must be either master, standby, or none
3117
Jon Halle3f39ff2015-01-13 11:50:53 -08003118 Returns:
3119 main.TRUE or main.FALSE based on argument verification and
3120 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003121 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003122 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003123 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003124 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003125 cmdStr = "device-role " +\
3126 str( deviceId ) + " " +\
3127 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003128 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003129 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003130 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003131 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003132 if re.search( "Error", handle ):
3133 # end color output to escape any colours
3134 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003135 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003136 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003137 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003138 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003139 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003140 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003141 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003142 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003143 except AssertionError:
3144 main.log.exception( "" )
3145 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003146 except TypeError:
3147 main.log.exception( self.name + ": Object not as expected" )
3148 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003149 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003150 main.log.error( self.name + ": EOF exception found" )
3151 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003152 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003153 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003154 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003155 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003156
kelvin-onlabd3b64892015-01-20 13:26:24 -08003157 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003158 """
Jon Hall0dd09952018-04-19 09:59:11 -07003159 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003160 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003161 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003162 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003163 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003164 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003165 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003166 cmdStr += " -j"
3167 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003168 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003169 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003170 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003171 except AssertionError:
3172 main.log.exception( "" )
3173 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003174 except TypeError:
3175 main.log.exception( self.name + ": Object not as expected" )
3176 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003177 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003178 main.log.error( self.name + ": EOF exception found" )
3179 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003180 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003181 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003182 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003183 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003184
kelvin-onlabd3b64892015-01-20 13:26:24 -08003185 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003186 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003187 CLI command to get the current leader for the Election test application
3188 NOTE: Requires installation of the onos-app-election feature
3189 Returns: Node IP of the leader if one exists
3190 None if none exists
3191 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003192 """
Jon Hall94fd0472014-12-08 11:52:42 -08003193 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003194 cmdStr = "election-test-leader"
3195 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003196 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003197 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003198 # Leader
3199 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003200 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003201 nodeSearch = re.search( leaderPattern, response )
3202 if nodeSearch:
3203 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003204 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003205 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003206 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003207 # no leader
3208 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003209 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003210 nullSearch = re.search( nullPattern, response )
3211 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003212 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003213 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003214 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003215 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003216 main.log.error( "Error in electionTestLeader on " + self.name +
3217 ": " + "unexpected response" )
3218 main.log.error( repr( response ) )
3219 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003220 except AssertionError:
3221 main.log.exception( "" )
3222 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003223 except TypeError:
3224 main.log.exception( self.name + ": Object not as expected" )
3225 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003226 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003227 main.log.error( self.name + ": EOF exception found" )
3228 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003229 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003230 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003231 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003232 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003233
kelvin-onlabd3b64892015-01-20 13:26:24 -08003234 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003235 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003236 CLI command to run for leadership of the Election test application.
3237 NOTE: Requires installation of the onos-app-election feature
3238 Returns: Main.TRUE on success
3239 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003240 """
Jon Hall94fd0472014-12-08 11:52:42 -08003241 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003242 cmdStr = "election-test-run"
3243 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003244 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003245 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003246 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003247 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003248 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003249 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003250 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003251 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003252 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003253 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003254 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003255 main.log.error( "Error in electionTestRun on " + self.name +
3256 ": " + "unexpected response" )
3257 main.log.error( repr( response ) )
3258 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003259 except AssertionError:
3260 main.log.exception( "" )
3261 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003262 except TypeError:
3263 main.log.exception( self.name + ": Object not as expected" )
3264 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003265 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003266 main.log.error( self.name + ": EOF exception found" )
3267 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003268 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003269 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003270 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003271 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003272
kelvin-onlabd3b64892015-01-20 13:26:24 -08003273 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003274 """
Jon Hall94fd0472014-12-08 11:52:42 -08003275 * CLI command to withdraw the local node from leadership election for
3276 * the Election test application.
3277 #NOTE: Requires installation of the onos-app-election feature
3278 Returns: Main.TRUE on success
3279 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003280 """
Jon Hall94fd0472014-12-08 11:52:42 -08003281 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003282 cmdStr = "election-test-withdraw"
3283 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003284 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003285 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003286 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003287 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003288 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003289 if re.search( successPattern, response ):
3290 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003291 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003292 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003293 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003294 main.log.error( "Error in electionTestWithdraw on " +
3295 self.name + ": " + "unexpected response" )
3296 main.log.error( repr( response ) )
3297 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003298 except AssertionError:
3299 main.log.exception( "" )
3300 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003301 except TypeError:
3302 main.log.exception( self.name + ": Object not as expected" )
3303 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003304 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003305 main.log.error( self.name + ": EOF exception found" )
3306 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003307 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003308 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003309 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003310 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003311
kelvin8ec71442015-01-15 16:57:00 -08003312 def getDevicePortsEnabledCount( self, dpid ):
3313 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003314 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003315 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003316 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003317 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003318 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3319 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003320 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003321 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003322 if re.search( "No such device", output ):
3323 main.log.error( "Error in getting ports" )
3324 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003325 return output
Jon Hallc6793552016-01-19 14:18:37 -08003326 except AssertionError:
3327 main.log.exception( "" )
3328 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003329 except TypeError:
3330 main.log.exception( self.name + ": Object not as expected" )
3331 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003332 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003333 main.log.error( self.name + ": EOF exception found" )
3334 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003335 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003336 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003337 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003338 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003339
kelvin8ec71442015-01-15 16:57:00 -08003340 def getDeviceLinksActiveCount( self, dpid ):
3341 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003342 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003343 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003344 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003345 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003346 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3347 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003348 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003349 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003350 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003351 main.log.error( "Error in getting ports " )
3352 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003353 return output
Jon Hallc6793552016-01-19 14:18:37 -08003354 except AssertionError:
3355 main.log.exception( "" )
3356 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003357 except TypeError:
3358 main.log.exception( self.name + ": Object not as expected" )
3359 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003360 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003361 main.log.error( self.name + ": EOF exception found" )
3362 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003363 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003364 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003365 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003366 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003367
kelvin8ec71442015-01-15 16:57:00 -08003368 def getAllIntentIds( self ):
3369 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003370 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003371 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003372 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003373 cmdStr = "onos:intents | grep id="
3374 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003375 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003376 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003377 if re.search( "Error", output ):
3378 main.log.error( "Error in getting ports" )
3379 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003380 return output
Jon Hallc6793552016-01-19 14:18:37 -08003381 except AssertionError:
3382 main.log.exception( "" )
3383 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003384 except TypeError:
3385 main.log.exception( self.name + ": Object not as expected" )
3386 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003387 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003388 main.log.error( self.name + ": EOF exception found" )
3389 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003390 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003391 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003392 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003393 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003394
Jon Hall73509952015-02-24 16:42:56 -08003395 def intentSummary( self ):
3396 """
Jon Hallefbd9792015-03-05 16:11:36 -08003397 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003398 """
3399 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003400 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003401 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003402 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003403 states.append( intent.get( 'state', None ) )
3404 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003405 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003406 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003407 except ( TypeError, ValueError ):
3408 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003409 return None
3410 except pexpect.EOF:
3411 main.log.error( self.name + ": EOF exception found" )
3412 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003413 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003414 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003415 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003416 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003417
Jon Hall61282e32015-03-19 11:34:11 -07003418 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003419 """
3420 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003421 Optional argument:
3422 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003423 """
Jon Hall63604932015-02-26 17:09:50 -08003424 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003425 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003426 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003427 cmdStr += " -j"
3428 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003429 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003430 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003431 return output
Jon Hallc6793552016-01-19 14:18:37 -08003432 except AssertionError:
3433 main.log.exception( "" )
3434 return None
Jon Hall63604932015-02-26 17:09:50 -08003435 except TypeError:
3436 main.log.exception( self.name + ": Object not as expected" )
3437 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003438 except pexpect.EOF:
3439 main.log.error( self.name + ": EOF exception found" )
3440 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003441 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003442 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003443 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003444 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003445
acsmarsa4a4d1e2015-07-10 16:01:24 -07003446 def leaderCandidates( self, jsonFormat=True ):
3447 """
3448 Returns the output of the leaders -c command.
3449 Optional argument:
3450 * jsonFormat - boolean indicating if you want output in json
3451 """
3452 try:
3453 cmdStr = "onos:leaders -c"
3454 if jsonFormat:
3455 cmdStr += " -j"
3456 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003457 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003458 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003459 return output
Jon Hallc6793552016-01-19 14:18:37 -08003460 except AssertionError:
3461 main.log.exception( "" )
3462 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003463 except TypeError:
3464 main.log.exception( self.name + ": Object not as expected" )
3465 return None
3466 except pexpect.EOF:
3467 main.log.error( self.name + ": EOF exception found" )
3468 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003469 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003470 except Exception:
3471 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003472 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003473
Jon Hallc6793552016-01-19 14:18:37 -08003474 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003475 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003476 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003477 topic parameter and an empty list if the topic doesn't exist
3478 If no leader is elected leader in the returned list will be "none"
3479 Returns None if there is a type error processing the json object
3480 """
3481 try:
Jon Hall6e709752016-02-01 13:38:46 -08003482 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003483 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003484 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003485 assert "Command not found:" not in rawOutput, rawOutput
3486 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003487 results = []
3488 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003489 if dict[ "topic" ] == topic:
3490 leader = dict[ "leader" ]
3491 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003492 results.append( leader )
3493 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003494 return results
Jon Hallc6793552016-01-19 14:18:37 -08003495 except AssertionError:
3496 main.log.exception( "" )
3497 return None
3498 except ( TypeError, ValueError ):
3499 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003500 return None
3501 except pexpect.EOF:
3502 main.log.error( self.name + ": EOF exception found" )
3503 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003504 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003505 except Exception:
3506 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003507 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003508
Jon Hall61282e32015-03-19 11:34:11 -07003509 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003510 """
3511 Returns the output of the intent Pending map.
3512 """
Jon Hall63604932015-02-26 17:09:50 -08003513 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003514 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003515 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003516 cmdStr += " -j"
3517 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003518 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003519 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003520 return output
Jon Hallc6793552016-01-19 14:18:37 -08003521 except AssertionError:
3522 main.log.exception( "" )
3523 return None
Jon Hall63604932015-02-26 17:09:50 -08003524 except TypeError:
3525 main.log.exception( self.name + ": Object not as expected" )
3526 return None
3527 except pexpect.EOF:
3528 main.log.error( self.name + ": EOF exception found" )
3529 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003530 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003531 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003532 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003533 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003534
Jon Hall2c8959e2016-12-16 12:17:34 -08003535 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003536 """
3537 Returns the output of the raft partitions command for ONOS.
3538 """
Jon Hall61282e32015-03-19 11:34:11 -07003539 # Sample JSON
3540 # {
3541 # "leader": "tcp://10.128.30.11:7238",
3542 # "members": [
3543 # "tcp://10.128.30.11:7238",
3544 # "tcp://10.128.30.17:7238",
3545 # "tcp://10.128.30.13:7238",
3546 # ],
3547 # "name": "p1",
3548 # "term": 3
3549 # },
Jon Hall63604932015-02-26 17:09:50 -08003550 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003551 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003552 if candidates:
3553 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003554 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003555 cmdStr += " -j"
3556 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003557 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003558 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003559 return output
Jon Hallc6793552016-01-19 14:18:37 -08003560 except AssertionError:
3561 main.log.exception( "" )
3562 return None
Jon Hall63604932015-02-26 17:09:50 -08003563 except TypeError:
3564 main.log.exception( self.name + ": Object not as expected" )
3565 return None
3566 except pexpect.EOF:
3567 main.log.error( self.name + ": EOF exception found" )
3568 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003569 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003570 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003571 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003572 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003573
Jon Halle9f909e2016-09-23 10:43:12 -07003574 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003575 """
3576 Returns the output of the apps command for ONOS. This command lists
3577 information about installed ONOS applications
3578 """
3579 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003580 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003581 # "description":"ONOS OpenFlow protocol southbound providers",
3582 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003583 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003584 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003585 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003586 if summary:
3587 cmdStr += " -s"
3588 if active:
3589 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003590 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003591 cmdStr += " -j"
3592 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003593 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003594 assert "Command not found:" not in output, output
3595 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003596 return output
Jon Hallbe379602015-03-24 13:39:32 -07003597 # FIXME: look at specific exceptions/Errors
3598 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003599 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003600 return None
3601 except TypeError:
3602 main.log.exception( self.name + ": Object not as expected" )
3603 return None
3604 except pexpect.EOF:
3605 main.log.error( self.name + ": EOF exception found" )
3606 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003607 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003608 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003609 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003610 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003611
Jon Hall146f1522015-03-24 15:33:24 -07003612 def appStatus( self, appName ):
3613 """
3614 Uses the onos:apps cli command to return the status of an application.
3615 Returns:
3616 "ACTIVE" - If app is installed and activated
3617 "INSTALLED" - If app is installed and deactivated
3618 "UNINSTALLED" - If app is not installed
3619 None - on error
3620 """
Jon Hall146f1522015-03-24 15:33:24 -07003621 try:
3622 if not isinstance( appName, types.StringType ):
3623 main.log.error( self.name + ".appStatus(): appName must be" +
3624 " a string" )
3625 return None
3626 output = self.apps( jsonFormat=True )
3627 appsJson = json.loads( output )
3628 state = None
3629 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003630 if appName == app.get( 'name' ):
3631 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003632 break
3633 if state == "ACTIVE" or state == "INSTALLED":
3634 return state
3635 elif state is None:
Jon Hall8bafdc02017-09-05 11:36:26 -07003636 main.log.warn( "{} app not found", appName )
Jon Hall146f1522015-03-24 15:33:24 -07003637 return "UNINSTALLED"
3638 elif state:
3639 main.log.error( "Unexpected state from 'onos:apps': " +
3640 str( state ) )
3641 return state
Jon Hallc6793552016-01-19 14:18:37 -08003642 except ( TypeError, ValueError ):
3643 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003644 return None
3645 except pexpect.EOF:
3646 main.log.error( self.name + ": EOF exception found" )
3647 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003648 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003649 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003650 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003651 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003652
Jon Hallbe379602015-03-24 13:39:32 -07003653 def app( self, appName, option ):
3654 """
3655 Interacts with the app command for ONOS. This command manages
3656 application inventory.
3657 """
Jon Hallbe379602015-03-24 13:39:32 -07003658 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003659 # Validate argument types
3660 valid = True
3661 if not isinstance( appName, types.StringType ):
3662 main.log.error( self.name + ".app(): appName must be a " +
3663 "string" )
3664 valid = False
3665 if not isinstance( option, types.StringType ):
3666 main.log.error( self.name + ".app(): option must be a string" )
3667 valid = False
3668 if not valid:
3669 return main.FALSE
3670 # Validate Option
3671 option = option.lower()
3672 # NOTE: Install may become a valid option
3673 if option == "activate":
3674 pass
3675 elif option == "deactivate":
3676 pass
3677 elif option == "uninstall":
3678 pass
3679 else:
3680 # Invalid option
3681 main.log.error( "The ONOS app command argument only takes " +
3682 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003683 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003684 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003685 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003686 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003687 assert output is not None, "Error in sendline"
3688 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003689 if "Error executing command" in output:
3690 main.log.error( "Error in processing onos:app command: " +
3691 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003692 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003693 elif "No such application" in output:
3694 main.log.error( "The application '" + appName +
3695 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003696 return main.FALSE
3697 elif "Command not found:" in output:
3698 main.log.error( "Error in processing onos:app command: " +
3699 str( output ) )
3700 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003701 elif "Unsupported command:" in output:
3702 main.log.error( "Incorrect command given to 'app': " +
3703 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003704 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003705 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003706 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003707 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003708 except AssertionError:
3709 main.log.exception( self.name + ": AssertionError exception found" )
3710 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003711 except TypeError:
3712 main.log.exception( self.name + ": Object not as expected" )
3713 return main.ERROR
3714 except pexpect.EOF:
3715 main.log.error( self.name + ": EOF exception found" )
3716 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003717 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003718 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003719 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003720 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003721
Jon Hallbd16b922015-03-26 17:53:15 -07003722 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003723 """
3724 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003725 appName is the hierarchical app name, not the feature name
3726 If check is True, method will check the status of the app after the
3727 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003728 Returns main.TRUE if the command was successfully sent
3729 main.FALSE if the cli responded with an error or given
3730 incorrect input
3731 """
3732 try:
3733 if not isinstance( appName, types.StringType ):
3734 main.log.error( self.name + ".activateApp(): appName must be" +
3735 " a string" )
3736 return main.FALSE
3737 status = self.appStatus( appName )
3738 if status == "INSTALLED":
3739 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003740 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003741 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003742 status = self.appStatus( appName )
3743 if status == "ACTIVE":
3744 return main.TRUE
3745 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003746 main.log.debug( "The state of application " +
3747 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003748 time.sleep( 1 )
3749 return main.FALSE
3750 else: # not 'check' or command didn't succeed
3751 return response
Jon Hall146f1522015-03-24 15:33:24 -07003752 elif status == "ACTIVE":
3753 return main.TRUE
3754 elif status == "UNINSTALLED":
3755 main.log.error( self.name + ": Tried to activate the " +
3756 "application '" + appName + "' which is not " +
3757 "installed." )
3758 else:
3759 main.log.error( "Unexpected return value from appStatus: " +
3760 str( status ) )
3761 return main.ERROR
3762 except TypeError:
3763 main.log.exception( self.name + ": Object not as expected" )
3764 return main.ERROR
3765 except pexpect.EOF:
3766 main.log.error( self.name + ": EOF exception found" )
3767 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003768 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003769 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003770 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003771 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003772
Jon Hallbd16b922015-03-26 17:53:15 -07003773 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003774 """
3775 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003776 appName is the hierarchical app name, not the feature name
3777 If check is True, method will check the status of the app after the
3778 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003779 Returns main.TRUE if the command was successfully sent
3780 main.FALSE if the cli responded with an error or given
3781 incorrect input
3782 """
3783 try:
3784 if not isinstance( appName, types.StringType ):
3785 main.log.error( self.name + ".deactivateApp(): appName must " +
3786 "be a string" )
3787 return main.FALSE
3788 status = self.appStatus( appName )
3789 if status == "INSTALLED":
3790 return main.TRUE
3791 elif status == "ACTIVE":
3792 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003793 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003794 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003795 status = self.appStatus( appName )
3796 if status == "INSTALLED":
3797 return main.TRUE
3798 else:
3799 time.sleep( 1 )
3800 return main.FALSE
3801 else: # not check or command didn't succeed
3802 return response
Jon Hall146f1522015-03-24 15:33:24 -07003803 elif status == "UNINSTALLED":
3804 main.log.warn( self.name + ": Tried to deactivate the " +
3805 "application '" + appName + "' which is not " +
3806 "installed." )
3807 return main.TRUE
3808 else:
3809 main.log.error( "Unexpected return value from appStatus: " +
3810 str( status ) )
3811 return main.ERROR
3812 except TypeError:
3813 main.log.exception( self.name + ": Object not as expected" )
3814 return main.ERROR
3815 except pexpect.EOF:
3816 main.log.error( self.name + ": EOF exception found" )
3817 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003818 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003819 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003820 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003821 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003822
Jon Hallbd16b922015-03-26 17:53:15 -07003823 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003824 """
3825 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003826 appName is the hierarchical app name, not the feature name
3827 If check is True, method will check the status of the app after the
3828 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003829 Returns main.TRUE if the command was successfully sent
3830 main.FALSE if the cli responded with an error or given
3831 incorrect input
3832 """
3833 # TODO: check with Thomas about the state machine for apps
3834 try:
3835 if not isinstance( appName, types.StringType ):
3836 main.log.error( self.name + ".uninstallApp(): appName must " +
3837 "be a string" )
3838 return main.FALSE
3839 status = self.appStatus( appName )
3840 if status == "INSTALLED":
3841 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003842 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003843 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003844 status = self.appStatus( appName )
3845 if status == "UNINSTALLED":
3846 return main.TRUE
3847 else:
3848 time.sleep( 1 )
3849 return main.FALSE
3850 else: # not check or command didn't succeed
3851 return response
Jon Hall146f1522015-03-24 15:33:24 -07003852 elif status == "ACTIVE":
3853 main.log.warn( self.name + ": Tried to uninstall the " +
3854 "application '" + appName + "' which is " +
3855 "currently active." )
3856 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003857 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003858 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003859 status = self.appStatus( appName )
3860 if status == "UNINSTALLED":
3861 return main.TRUE
3862 else:
3863 time.sleep( 1 )
3864 return main.FALSE
3865 else: # not check or command didn't succeed
3866 return response
Jon Hall146f1522015-03-24 15:33:24 -07003867 elif status == "UNINSTALLED":
3868 return main.TRUE
3869 else:
3870 main.log.error( "Unexpected return value from appStatus: " +
3871 str( status ) )
3872 return main.ERROR
3873 except TypeError:
3874 main.log.exception( self.name + ": Object not as expected" )
3875 return main.ERROR
3876 except pexpect.EOF:
3877 main.log.error( self.name + ": EOF exception found" )
3878 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003879 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003880 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003881 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003882 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003883
3884 def appIDs( self, jsonFormat=True ):
3885 """
3886 Show the mappings between app id and app names given by the 'app-ids'
3887 cli command
3888 """
3889 try:
3890 cmdStr = "app-ids"
3891 if jsonFormat:
3892 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003893 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003894 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003895 assert "Command not found:" not in output, output
3896 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003897 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003898 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003899 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003900 return None
3901 except TypeError:
3902 main.log.exception( self.name + ": Object not as expected" )
3903 return None
3904 except pexpect.EOF:
3905 main.log.error( self.name + ": EOF exception found" )
3906 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003907 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003908 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003909 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003910 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003911
3912 def appToIDCheck( self ):
3913 """
3914 This method will check that each application's ID listed in 'apps' is
3915 the same as the ID listed in 'app-ids'. The check will also check that
3916 there are no duplicate IDs issued. Note that an app ID should be
3917 a globaly unique numerical identifier for app/app-like features. Once
3918 an ID is registered, the ID is never freed up so that if an app is
3919 reinstalled it will have the same ID.
3920
3921 Returns: main.TRUE if the check passes and
3922 main.FALSE if the check fails or
3923 main.ERROR if there is some error in processing the test
3924 """
3925 try:
Jon Hall390696c2015-05-05 17:13:41 -07003926 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003927 rawJson = self.appIDs( jsonFormat=True )
3928 if rawJson:
3929 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003930 else:
Jon Hallc6793552016-01-19 14:18:37 -08003931 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003932 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003933 rawJson = self.apps( jsonFormat=True )
3934 if rawJson:
3935 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003936 else:
Jon Hallc6793552016-01-19 14:18:37 -08003937 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003938 bail = True
3939 if bail:
3940 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003941 result = main.TRUE
3942 for app in apps:
3943 appID = app.get( 'id' )
3944 if appID is None:
3945 main.log.error( "Error parsing app: " + str( app ) )
3946 result = main.FALSE
3947 appName = app.get( 'name' )
3948 if appName is None:
3949 main.log.error( "Error parsing app: " + str( app ) )
3950 result = main.FALSE
3951 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003952 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07003953 if not current: # if ids doesn't have this id
3954 result = main.FALSE
3955 main.log.error( "'app-ids' does not have the ID for " +
3956 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08003957 main.log.debug( "apps command returned: " + str( app ) +
3958 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003959 elif len( current ) > 1:
3960 # there is more than one app with this ID
3961 result = main.FALSE
3962 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003963 elif not current[ 0 ][ 'name' ] == appName:
3964 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07003965 result = main.FALSE
3966 main.log.error( "'app-ids' has " + str( currentName ) +
3967 " registered under id:" + str( appID ) +
3968 " but 'apps' has " + str( appName ) )
3969 else:
3970 pass # id and name match!
3971 # now make sure that app-ids has no duplicates
3972 idsList = []
3973 namesList = []
3974 for item in ids:
3975 idsList.append( item[ 'id' ] )
3976 namesList.append( item[ 'name' ] )
3977 if len( idsList ) != len( set( idsList ) ) or\
3978 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003979 main.log.error( "'app-ids' has some duplicate entries: \n"
3980 + json.dumps( ids,
3981 sort_keys=True,
3982 indent=4,
3983 separators=( ',', ': ' ) ) )
3984 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003985 return result
Jon Hallc6793552016-01-19 14:18:37 -08003986 except ( TypeError, ValueError ):
3987 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003988 return main.ERROR
3989 except pexpect.EOF:
3990 main.log.error( self.name + ": EOF exception found" )
3991 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003992 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003993 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003994 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003995 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003996
Jon Hallfb760a02015-04-13 15:35:03 -07003997 def getCfg( self, component=None, propName=None, short=False,
3998 jsonFormat=True ):
3999 """
4000 Get configuration settings from onos cli
4001 Optional arguments:
4002 component - Optionally only list configurations for a specific
4003 component. If None, all components with configurations
4004 are displayed. Case Sensitive string.
4005 propName - If component is specified, propName option will show
4006 only this specific configuration from that component.
4007 Case Sensitive string.
4008 jsonFormat - Returns output as json. Note that this will override
4009 the short option
4010 short - Short, less verbose, version of configurations.
4011 This is overridden by the json option
4012 returns:
4013 Output from cli as a string or None on error
4014 """
4015 try:
4016 baseStr = "cfg"
4017 cmdStr = " get"
4018 componentStr = ""
4019 if component:
4020 componentStr += " " + component
4021 if propName:
4022 componentStr += " " + propName
4023 if jsonFormat:
4024 baseStr += " -j"
4025 elif short:
4026 baseStr += " -s"
4027 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004028 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004029 assert "Command not found:" not in output, output
4030 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004031 return output
4032 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004033 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004034 return None
4035 except TypeError:
4036 main.log.exception( self.name + ": Object not as expected" )
4037 return None
4038 except pexpect.EOF:
4039 main.log.error( self.name + ": EOF exception found" )
4040 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004041 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004042 except Exception:
4043 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004044 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004045
4046 def setCfg( self, component, propName, value=None, check=True ):
4047 """
4048 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004049 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004050 component - The case sensitive name of the component whose
4051 property is to be set
4052 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004053 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004054 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004055 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004056 check - Boolean, Check whether the option was successfully set this
4057 only applies when a value is given.
4058 returns:
4059 main.TRUE on success or main.FALSE on failure. If check is False,
4060 will return main.TRUE unless there is an error
4061 """
4062 try:
4063 baseStr = "cfg"
4064 cmdStr = " set " + str( component ) + " " + str( propName )
4065 if value is not None:
4066 cmdStr += " " + str( value )
4067 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004068 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004069 assert "Command not found:" not in output, output
4070 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004071 if value and check:
4072 results = self.getCfg( component=str( component ),
4073 propName=str( propName ),
4074 jsonFormat=True )
4075 # Check if current value is what we just set
4076 try:
4077 jsonOutput = json.loads( results )
4078 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004079 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004080 main.log.exception( "Error parsing cfg output" )
4081 main.log.error( "output:" + repr( results ) )
4082 return main.FALSE
4083 if current == str( value ):
4084 return main.TRUE
4085 return main.FALSE
4086 return main.TRUE
4087 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004088 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004089 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004090 except ( TypeError, ValueError ):
4091 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004092 return main.FALSE
4093 except pexpect.EOF:
4094 main.log.error( self.name + ": EOF exception found" )
4095 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004096 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004097 except Exception:
4098 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004099 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004100
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004101 def distPrimitivesSend( self, cmd ):
4102 """
4103 Function to handle sending cli commands for the distributed primitives test app
4104
4105 This command will catch some exceptions and retry the command on some
4106 specific store exceptions.
4107
4108 Required arguments:
4109 cmd - The command to send to the cli
4110 returns:
4111 string containing the cli output
4112 None on Error
4113 """
4114 try:
4115 output = self.sendline( cmd )
4116 try:
4117 assert output is not None, "Error in sendline"
4118 # TODO: Maybe make this less hardcoded
4119 # ConsistentMap Exceptions
4120 assert "org.onosproject.store.service" not in output
4121 # Node not leader
4122 assert "java.lang.IllegalStateException" not in output
4123 except AssertionError:
4124 main.log.error( "Error in processing '" + cmd + "' " +
4125 "command: " + str( output ) )
4126 retryTime = 30 # Conservative time, given by Madan
4127 main.log.info( "Waiting " + str( retryTime ) +
4128 "seconds before retrying." )
4129 time.sleep( retryTime ) # Due to change in mastership
4130 output = self.sendline( cmd )
4131 assert output is not None, "Error in sendline"
4132 assert "Command not found:" not in output, output
4133 assert "Error executing command" not in output, output
4134 main.log.info( self.name + ": " + output )
4135 return output
4136 except AssertionError:
4137 main.log.exception( "Error in processing '" + cmd + "' command." )
4138 return None
4139 except TypeError:
4140 main.log.exception( self.name + ": Object not as expected" )
4141 return None
4142 except pexpect.EOF:
4143 main.log.error( self.name + ": EOF exception found" )
4144 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004145 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004146 except Exception:
4147 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004148 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004149
Jon Hall390696c2015-05-05 17:13:41 -07004150 def setTestAdd( self, setName, values ):
4151 """
4152 CLI command to add elements to a distributed set.
4153 Arguments:
4154 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004155 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004156 Example usages:
4157 setTestAdd( "set1", "a b c" )
4158 setTestAdd( "set2", "1" )
4159 returns:
4160 main.TRUE on success OR
4161 main.FALSE if elements were already in the set OR
4162 main.ERROR on error
4163 """
4164 try:
4165 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004166 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004167 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4168 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004169 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004170 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004171 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004172 return main.FALSE
4173 else:
4174 main.log.error( self.name + ": setTestAdd did not" +
4175 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004176 main.log.debug( self.name + " actual: " + repr( output ) )
4177 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004178 except TypeError:
4179 main.log.exception( self.name + ": Object not as expected" )
4180 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004181 except Exception:
4182 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004183 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004184
4185 def setTestRemove( self, setName, values, clear=False, retain=False ):
4186 """
4187 CLI command to remove elements from a distributed set.
4188 Required arguments:
4189 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004190 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004191 Optional arguments:
4192 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004193 retain - Retain only the given values. (intersection of the
4194 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004195 returns:
4196 main.TRUE on success OR
4197 main.FALSE if the set was not changed OR
4198 main.ERROR on error
4199 """
4200 try:
4201 cmdStr = "set-test-remove "
4202 if clear:
4203 cmdStr += "-c " + str( setName )
4204 elif retain:
4205 cmdStr += "-r " + str( setName ) + " " + str( values )
4206 else:
4207 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004208 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004209 if clear:
4210 pattern = "Set " + str( setName ) + " cleared"
4211 if re.search( pattern, output ):
4212 return main.TRUE
4213 elif retain:
4214 positivePattern = str( setName ) + " was pruned to contain " +\
4215 "only elements of set \[(.*)\]"
4216 negativePattern = str( setName ) + " was not changed by " +\
4217 "retaining only elements of the set " +\
4218 "\[(.*)\]"
4219 if re.search( positivePattern, output ):
4220 return main.TRUE
4221 elif re.search( negativePattern, output ):
4222 return main.FALSE
4223 else:
4224 positivePattern = "\[(.*)\] was removed from the set " +\
4225 str( setName )
4226 if ( len( values.split() ) == 1 ):
4227 negativePattern = "\[(.*)\] was not in set " +\
4228 str( setName )
4229 else:
4230 negativePattern = "No element of \[(.*)\] was in set " +\
4231 str( setName )
4232 if re.search( positivePattern, output ):
4233 return main.TRUE
4234 elif re.search( negativePattern, output ):
4235 return main.FALSE
4236 main.log.error( self.name + ": setTestRemove did not" +
4237 " match expected output" )
4238 main.log.debug( self.name + " expected: " + pattern )
4239 main.log.debug( self.name + " actual: " + repr( output ) )
4240 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004241 except TypeError:
4242 main.log.exception( self.name + ": Object not as expected" )
4243 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004244 except Exception:
4245 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004246 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004247
4248 def setTestGet( self, setName, values="" ):
4249 """
4250 CLI command to get the elements in a distributed set.
4251 Required arguments:
4252 setName - The name of the set to remove from.
4253 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004254 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004255 returns:
4256 main.ERROR on error OR
4257 A list of elements in the set if no optional arguments are
4258 supplied OR
4259 A tuple containing the list then:
4260 main.FALSE if the given values are not in the set OR
4261 main.TRUE if the given values are in the set OR
4262 """
4263 try:
4264 values = str( values ).strip()
4265 setName = str( setName ).strip()
4266 length = len( values.split() )
4267 containsCheck = None
4268 # Patterns to match
4269 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004270 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004271 containsTrue = "Set " + setName + " contains the value " + values
4272 containsFalse = "Set " + setName + " did not contain the value " +\
4273 values
4274 containsAllTrue = "Set " + setName + " contains the the subset " +\
4275 setPattern
4276 containsAllFalse = "Set " + setName + " did not contain the the" +\
4277 " subset " + setPattern
4278
4279 cmdStr = "set-test-get "
4280 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004281 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004282 if length == 0:
4283 match = re.search( pattern, output )
4284 else: # if given values
4285 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004286 patternTrue = pattern + "\r\n" + containsTrue
4287 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004288 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004289 patternTrue = pattern + "\r\n" + containsAllTrue
4290 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004291 matchTrue = re.search( patternTrue, output )
4292 matchFalse = re.search( patternFalse, output )
4293 if matchTrue:
4294 containsCheck = main.TRUE
4295 match = matchTrue
4296 elif matchFalse:
4297 containsCheck = main.FALSE
4298 match = matchFalse
4299 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004300 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004301 "expected output" )
4302 main.log.debug( self.name + " expected: " + pattern )
4303 main.log.debug( self.name + " actual: " + repr( output ) )
4304 match = None
4305 if match:
4306 setMatch = match.group( 1 )
4307 if setMatch == '':
4308 setList = []
4309 else:
4310 setList = setMatch.split( ", " )
4311 if length > 0:
4312 return ( setList, containsCheck )
4313 else:
4314 return setList
4315 else: # no match
4316 main.log.error( self.name + ": setTestGet did not" +
4317 " match expected output" )
4318 main.log.debug( self.name + " expected: " + pattern )
4319 main.log.debug( self.name + " actual: " + repr( output ) )
4320 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004321 except TypeError:
4322 main.log.exception( self.name + ": Object not as expected" )
4323 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004324 except Exception:
4325 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004326 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004327
4328 def setTestSize( self, setName ):
4329 """
4330 CLI command to get the elements in a distributed set.
4331 Required arguments:
4332 setName - The name of the set to remove from.
4333 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004334 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004335 None on error
4336 """
4337 try:
4338 # TODO: Should this check against the number of elements returned
4339 # and then return true/false based on that?
4340 setName = str( setName ).strip()
4341 # Patterns to match
4342 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004343 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004344 setPattern
4345 cmdStr = "set-test-get -s "
4346 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004347 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004348 match = re.search( pattern, output )
4349 if match:
4350 setSize = int( match.group( 1 ) )
4351 setMatch = match.group( 2 )
4352 if len( setMatch.split() ) == setSize:
4353 main.log.info( "The size returned by " + self.name +
4354 " matches the number of elements in " +
4355 "the returned set" )
4356 else:
4357 main.log.error( "The size returned by " + self.name +
4358 " does not match the number of " +
4359 "elements in the returned set." )
4360 return setSize
4361 else: # no match
4362 main.log.error( self.name + ": setTestGet did not" +
4363 " match expected output" )
4364 main.log.debug( self.name + " expected: " + pattern )
4365 main.log.debug( self.name + " actual: " + repr( output ) )
4366 return None
Jon Hall390696c2015-05-05 17:13:41 -07004367 except TypeError:
4368 main.log.exception( self.name + ": Object not as expected" )
4369 return None
Jon Hall390696c2015-05-05 17:13:41 -07004370 except Exception:
4371 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004372 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004373
Jon Hall80daded2015-05-27 16:07:00 -07004374 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004375 """
4376 Command to list the various counters in the system.
4377 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004378 if jsonFormat, a string of the json object returned by the cli
4379 command
4380 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004381 None on error
4382 """
Jon Hall390696c2015-05-05 17:13:41 -07004383 try:
Jon Hall390696c2015-05-05 17:13:41 -07004384 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004385 if jsonFormat:
4386 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004387 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004388 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004389 assert "Command not found:" not in output, output
4390 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004391 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004392 return output
Jon Hall390696c2015-05-05 17:13:41 -07004393 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004394 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004395 return None
Jon Hall390696c2015-05-05 17:13:41 -07004396 except TypeError:
4397 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004398 return None
Jon Hall390696c2015-05-05 17:13:41 -07004399 except pexpect.EOF:
4400 main.log.error( self.name + ": EOF exception found" )
4401 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004402 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004403 except Exception:
4404 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004405 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004406
Jon Hall935db192016-04-19 00:22:04 -07004407 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004408 """
Jon Halle1a3b752015-07-22 13:02:46 -07004409 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004410 Required arguments:
4411 counter - The name of the counter to increment.
4412 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004413 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004414 returns:
4415 integer value of the counter or
4416 None on Error
4417 """
4418 try:
4419 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004420 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004421 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004422 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004423 if delta != 1:
4424 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004425 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004426 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004427 match = re.search( pattern, output )
4428 if match:
4429 return int( match.group( 1 ) )
4430 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004431 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004432 " match expected output." )
4433 main.log.debug( self.name + " expected: " + pattern )
4434 main.log.debug( self.name + " actual: " + repr( output ) )
4435 return None
Jon Hall390696c2015-05-05 17:13:41 -07004436 except TypeError:
4437 main.log.exception( self.name + ": Object not as expected" )
4438 return None
Jon Hall390696c2015-05-05 17:13:41 -07004439 except Exception:
4440 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004441 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004442
Jon Hall935db192016-04-19 00:22:04 -07004443 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004444 """
4445 CLI command to get a distributed counter then add a delta to it.
4446 Required arguments:
4447 counter - The name of the counter to increment.
4448 Optional arguments:
4449 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004450 returns:
4451 integer value of the counter or
4452 None on Error
4453 """
4454 try:
4455 counter = str( counter )
4456 delta = int( delta )
4457 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004458 cmdStr += counter
4459 if delta != 1:
4460 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004461 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004462 pattern = counter + " was updated to (-?\d+)"
4463 match = re.search( pattern, output )
4464 if match:
4465 return int( match.group( 1 ) )
4466 else:
4467 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4468 " match expected output." )
4469 main.log.debug( self.name + " expected: " + pattern )
4470 main.log.debug( self.name + " actual: " + repr( output ) )
4471 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004472 except TypeError:
4473 main.log.exception( self.name + ": Object not as expected" )
4474 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004475 except Exception:
4476 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004477 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004478
4479 def valueTestGet( self, valueName ):
4480 """
4481 CLI command to get the value of an atomic value.
4482 Required arguments:
4483 valueName - The name of the value to get.
4484 returns:
4485 string value of the value or
4486 None on Error
4487 """
4488 try:
4489 valueName = str( valueName )
4490 cmdStr = "value-test "
4491 operation = "get"
4492 cmdStr = "value-test {} {}".format( valueName,
4493 operation )
4494 output = self.distPrimitivesSend( cmdStr )
4495 pattern = "(\w+)"
4496 match = re.search( pattern, output )
4497 if match:
4498 return match.group( 1 )
4499 else:
4500 main.log.error( self.name + ": valueTestGet did not" +
4501 " match expected output." )
4502 main.log.debug( self.name + " expected: " + pattern )
4503 main.log.debug( self.name + " actual: " + repr( output ) )
4504 return None
4505 except TypeError:
4506 main.log.exception( self.name + ": Object not as expected" )
4507 return None
4508 except Exception:
4509 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004510 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004511
4512 def valueTestSet( self, valueName, newValue ):
4513 """
4514 CLI command to set the value of an atomic value.
4515 Required arguments:
4516 valueName - The name of the value to set.
4517 newValue - The value to assign to the given value.
4518 returns:
4519 main.TRUE on success or
4520 main.ERROR on Error
4521 """
4522 try:
4523 valueName = str( valueName )
4524 newValue = str( newValue )
4525 operation = "set"
4526 cmdStr = "value-test {} {} {}".format( valueName,
4527 operation,
4528 newValue )
4529 output = self.distPrimitivesSend( cmdStr )
4530 if output is not None:
4531 return main.TRUE
4532 else:
4533 return main.ERROR
4534 except TypeError:
4535 main.log.exception( self.name + ": Object not as expected" )
4536 return main.ERROR
4537 except Exception:
4538 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004539 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004540
4541 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4542 """
4543 CLI command to compareAndSet the value of an atomic value.
4544 Required arguments:
4545 valueName - The name of the value.
4546 oldValue - Compare the current value of the atomic value to this
4547 newValue - If the value equals oldValue, set the value to newValue
4548 returns:
4549 main.TRUE on success or
4550 main.FALSE on failure or
4551 main.ERROR on Error
4552 """
4553 try:
4554 valueName = str( valueName )
4555 oldValue = str( oldValue )
4556 newValue = str( newValue )
4557 operation = "compareAndSet"
4558 cmdStr = "value-test {} {} {} {}".format( valueName,
4559 operation,
4560 oldValue,
4561 newValue )
4562 output = self.distPrimitivesSend( cmdStr )
4563 pattern = "(\w+)"
4564 match = re.search( pattern, output )
4565 if match:
4566 result = match.group( 1 )
4567 if result == "true":
4568 return main.TRUE
4569 elif result == "false":
4570 return main.FALSE
4571 else:
4572 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4573 " match expected output." )
4574 main.log.debug( self.name + " expected: " + pattern )
4575 main.log.debug( self.name + " actual: " + repr( output ) )
4576 return main.ERROR
4577 except TypeError:
4578 main.log.exception( self.name + ": Object not as expected" )
4579 return main.ERROR
4580 except Exception:
4581 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004582 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004583
4584 def valueTestGetAndSet( self, valueName, newValue ):
4585 """
4586 CLI command to getAndSet the value of an atomic value.
4587 Required arguments:
4588 valueName - The name of the value to get.
4589 newValue - The value to assign to the given value
4590 returns:
4591 string value of the value or
4592 None on Error
4593 """
4594 try:
4595 valueName = str( valueName )
4596 cmdStr = "value-test "
4597 operation = "getAndSet"
4598 cmdStr += valueName + " " + operation
4599 cmdStr = "value-test {} {} {}".format( valueName,
4600 operation,
4601 newValue )
4602 output = self.distPrimitivesSend( cmdStr )
4603 pattern = "(\w+)"
4604 match = re.search( pattern, output )
4605 if match:
4606 return match.group( 1 )
4607 else:
4608 main.log.error( self.name + ": valueTestGetAndSet did not" +
4609 " match expected output." )
4610 main.log.debug( self.name + " expected: " + pattern )
4611 main.log.debug( self.name + " actual: " + repr( output ) )
4612 return None
4613 except TypeError:
4614 main.log.exception( self.name + ": Object not as expected" )
4615 return None
4616 except Exception:
4617 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004618 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004619
4620 def valueTestDestroy( self, valueName ):
4621 """
4622 CLI command to destroy an atomic value.
4623 Required arguments:
4624 valueName - The name of the value to destroy.
4625 returns:
4626 main.TRUE on success or
4627 main.ERROR on Error
4628 """
4629 try:
4630 valueName = str( valueName )
4631 cmdStr = "value-test "
4632 operation = "destroy"
4633 cmdStr += valueName + " " + operation
4634 output = self.distPrimitivesSend( cmdStr )
4635 if output is not None:
4636 return main.TRUE
4637 else:
4638 return main.ERROR
4639 except TypeError:
4640 main.log.exception( self.name + ": Object not as expected" )
4641 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004642 except Exception:
4643 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004644 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004645
YPZhangfebf7302016-05-24 16:45:56 -07004646 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004647 """
4648 Description: Execute summary command in onos
4649 Returns: json object ( summary -j ), returns main.FALSE if there is
4650 no output
4651
4652 """
4653 try:
4654 cmdStr = "summary"
4655 if jsonFormat:
4656 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004657 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004658 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004659 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004660 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004661 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004662 if not handle:
4663 main.log.error( self.name + ": There is no output in " +
4664 "summary command" )
4665 return main.FALSE
4666 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004667 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004668 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004669 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004670 except TypeError:
4671 main.log.exception( self.name + ": Object not as expected" )
4672 return None
4673 except pexpect.EOF:
4674 main.log.error( self.name + ": EOF exception found" )
4675 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004676 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004677 except Exception:
4678 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004679 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004680
Jon Hall935db192016-04-19 00:22:04 -07004681 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004682 """
4683 CLI command to get the value of a key in a consistent map using
4684 transactions. This a test function and can only get keys from the
4685 test map hard coded into the cli command
4686 Required arguments:
4687 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004688 returns:
4689 The string value of the key or
4690 None on Error
4691 """
4692 try:
4693 keyName = str( keyName )
4694 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004695 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004696 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004697 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4698 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004699 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004700 return None
4701 else:
4702 match = re.search( pattern, output )
4703 if match:
4704 return match.groupdict()[ 'value' ]
4705 else:
4706 main.log.error( self.name + ": transactionlMapGet did not" +
4707 " match expected output." )
4708 main.log.debug( self.name + " expected: " + pattern )
4709 main.log.debug( self.name + " actual: " + repr( output ) )
4710 return None
4711 except TypeError:
4712 main.log.exception( self.name + ": Object not as expected" )
4713 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004714 except Exception:
4715 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004716 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004717
Jon Hall935db192016-04-19 00:22:04 -07004718 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004719 """
4720 CLI command to put a value into 'numKeys' number of keys in a
4721 consistent map using transactions. This a test function and can only
4722 put into keys named 'Key#' of the test map hard coded into the cli command
4723 Required arguments:
4724 numKeys - Number of keys to add the value to
4725 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004726 returns:
4727 A dictionary whose keys are the name of the keys put into the map
4728 and the values of the keys are dictionaries whose key-values are
4729 'value': value put into map and optionaly
4730 'oldValue': Previous value in the key or
4731 None on Error
4732
4733 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004734 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4735 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004736 """
4737 try:
4738 numKeys = str( numKeys )
4739 value = str( value )
4740 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004741 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004742 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004743 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4744 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4745 results = {}
4746 for line in output.splitlines():
4747 new = re.search( newPattern, line )
4748 updated = re.search( updatedPattern, line )
4749 if new:
4750 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4751 elif updated:
4752 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004753 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004754 else:
4755 main.log.error( self.name + ": transactionlMapGet did not" +
4756 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004757 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4758 newPattern,
4759 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004760 main.log.debug( self.name + " actual: " + repr( output ) )
4761 return results
4762 except TypeError:
4763 main.log.exception( self.name + ": Object not as expected" )
4764 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004765 except Exception:
4766 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004767 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004768
acsmarsdaea66c2015-09-03 11:44:06 -07004769 def maps( self, jsonFormat=True ):
4770 """
4771 Description: Returns result of onos:maps
4772 Optional:
4773 * jsonFormat: enable json formatting of output
4774 """
4775 try:
4776 cmdStr = "maps"
4777 if jsonFormat:
4778 cmdStr += " -j"
4779 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004780 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004781 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004782 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004783 except AssertionError:
4784 main.log.exception( "" )
4785 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004786 except TypeError:
4787 main.log.exception( self.name + ": Object not as expected" )
4788 return None
4789 except pexpect.EOF:
4790 main.log.error( self.name + ": EOF exception found" )
4791 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004792 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004793 except Exception:
4794 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004795 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004796
4797 def getSwController( self, uri, jsonFormat=True ):
4798 """
4799 Descrition: Gets the controller information from the device
4800 """
4801 try:
4802 cmd = "device-controllers "
4803 if jsonFormat:
4804 cmd += "-j "
4805 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004806 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004807 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004808 return response
Jon Hallc6793552016-01-19 14:18:37 -08004809 except AssertionError:
4810 main.log.exception( "" )
4811 return None
GlennRC050596c2015-11-18 17:06:41 -08004812 except TypeError:
4813 main.log.exception( self.name + ": Object not as expected" )
4814 return None
4815 except pexpect.EOF:
4816 main.log.error( self.name + ": EOF exception found" )
4817 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004818 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004819 except Exception:
4820 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004821 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004822
4823 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4824 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004825 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004826
4827 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004828 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08004829 ip - String or List: The ip address of the controller.
4830 This parameter can be formed in a couple of different ways.
4831 VALID:
4832 10.0.0.1 - just the ip address
4833 tcp:10.0.0.1 - the protocol and the ip address
4834 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4835 so that you can add controllers with different
4836 protocols and ports
4837 INVALID:
4838 10.0.0.1:6653 - this is not supported by ONOS
4839
4840 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4841 port - The port number.
4842 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4843
4844 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4845 """
4846 try:
4847 cmd = "device-setcontrollers"
4848
4849 if jsonFormat:
4850 cmd += " -j"
4851 cmd += " " + uri
4852 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004853 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08004854 for item in ip:
4855 if ":" in item:
4856 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004857 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08004858 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004859 elif "." in sitem[ 1 ]:
4860 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08004861 else:
4862 main.log.error( "Malformed entry: " + item )
4863 raise TypeError
4864 else:
4865 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004866 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004867 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004868 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004869 if "Error" in response:
4870 main.log.error( response )
4871 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004872 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004873 except AssertionError:
4874 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004875 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004876 except TypeError:
4877 main.log.exception( self.name + ": Object not as expected" )
4878 return main.FALSE
4879 except pexpect.EOF:
4880 main.log.error( self.name + ": EOF exception found" )
4881 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004882 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004883 except Exception:
4884 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004885 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004886
4887 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004888 '''
GlennRC20fc6522015-12-23 23:26:57 -08004889 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004890 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08004891 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004892 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08004893 Returns:
4894 Returns main.FALSE if an exception is thrown or an error is present
4895 in the response. Otherwise, returns main.TRUE.
4896 NOTE:
4897 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004898 '''
GlennRC20fc6522015-12-23 23:26:57 -08004899 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004900 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07004901 deviceStr = device
4902 device = []
4903 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004904
4905 for d in device:
4906 time.sleep( 1 )
4907 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004908 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004909 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004910 if "Error" in response:
4911 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4912 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004913 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004914 except AssertionError:
4915 main.log.exception( "" )
4916 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004917 except TypeError:
4918 main.log.exception( self.name + ": Object not as expected" )
4919 return main.FALSE
4920 except pexpect.EOF:
4921 main.log.error( self.name + ": EOF exception found" )
4922 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004923 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004924 except Exception:
4925 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004926 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004927
4928 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004929 '''
GlennRC20fc6522015-12-23 23:26:57 -08004930 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004931 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08004932 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004933 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08004934 Returns:
4935 Returns main.FALSE if an exception is thrown or an error is present
4936 in the response. Otherwise, returns main.TRUE.
4937 NOTE:
4938 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004939 '''
GlennRC20fc6522015-12-23 23:26:57 -08004940 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004941 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08004942 host = list( host )
4943
4944 for h in host:
4945 time.sleep( 1 )
4946 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004947 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004948 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004949 if "Error" in response:
4950 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4951 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004952 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004953 except AssertionError:
4954 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004955 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004956 except TypeError:
4957 main.log.exception( self.name + ": Object not as expected" )
4958 return main.FALSE
4959 except pexpect.EOF:
4960 main.log.error( self.name + ": EOF exception found" )
4961 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004962 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004963 except Exception:
4964 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004965 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004966
YPZhangfebf7302016-05-24 16:45:56 -07004967 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004968 '''
GlennRCed771242016-01-13 17:02:47 -08004969 Description:
4970 Bring link down or up in the null-provider.
4971 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004972 begin - (string) One end of a device or switch.
4973 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08004974 returns:
4975 main.TRUE if no exceptions were thrown and no Errors are
4976 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004977 '''
GlennRCed771242016-01-13 17:02:47 -08004978 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004979 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004980 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004981 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004982 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004983 if "Error" in response or "Failure" in response:
4984 main.log.error( response )
4985 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004986 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004987 except AssertionError:
4988 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004989 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004990 except TypeError:
4991 main.log.exception( self.name + ": Object not as expected" )
4992 return main.FALSE
4993 except pexpect.EOF:
4994 main.log.error( self.name + ": EOF exception found" )
4995 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004996 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004997 except Exception:
4998 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004999 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005000
Jon Hall2c8959e2016-12-16 12:17:34 -08005001 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005002 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005003 Description:
5004 Changes the state of port in an OF switch by means of the
5005 PORTSTATUS OF messages.
5006 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005007 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5008 port - (string) target port in the device. Ex: '2'
5009 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005010 returns:
5011 main.TRUE if no exceptions were thrown and no Errors are
5012 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005013 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005014 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005015 state = state.lower()
5016 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005017 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005018 response = self.sendline( cmd, showResponse=True )
5019 assert response is not None, "Error in sendline"
5020 assert "Command not found:" not in response, response
5021 if "Error" in response or "Failure" in response:
5022 main.log.error( response )
5023 return main.FALSE
5024 return main.TRUE
5025 except AssertionError:
5026 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005027 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005028 except TypeError:
5029 main.log.exception( self.name + ": Object not as expected" )
5030 return main.FALSE
5031 except pexpect.EOF:
5032 main.log.error( self.name + ": EOF exception found" )
5033 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005034 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005035 except Exception:
5036 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005037 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005038
5039 def logSet( self, level="INFO", app="org.onosproject" ):
5040 """
5041 Set the logging level to lvl for a specific app
5042 returns main.TRUE on success
5043 returns main.FALSE if Error occurred
5044 if noExit is True, TestON will not exit, but clean up
5045 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5046 Level defaults to INFO
5047 """
5048 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005049 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005050 self.handle.expect( "onos>" )
5051
5052 response = self.handle.before
5053 if re.search( "Error", response ):
5054 return main.FALSE
5055 return main.TRUE
5056 except pexpect.TIMEOUT:
5057 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005058 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005059 except pexpect.EOF:
5060 main.log.error( self.name + ": EOF exception found" )
5061 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005062 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005063 except Exception:
5064 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005065 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005066
5067 def getGraphDict( self, timeout=60, includeHost=False ):
5068 """
5069 Return a dictionary which describes the latest network topology data as a
5070 graph.
5071 An example of the dictionary:
5072 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5073 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5074 Each vertex should at least have an 'edges' attribute which describes the
5075 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005076 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005077 list of attributes.
5078 An example of the edges dictionary:
5079 'edges': { vertex2: { 'port': ..., 'weight': ... },
5080 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005081 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005082 in topology data.
5083 """
5084 graphDict = {}
5085 try:
5086 links = self.links()
5087 links = json.loads( links )
5088 devices = self.devices()
5089 devices = json.loads( devices )
5090 idToDevice = {}
5091 for device in devices:
5092 idToDevice[ device[ 'id' ] ] = device
5093 if includeHost:
5094 hosts = self.hosts()
5095 # FIXME: support 'includeHost' argument
5096 for link in links:
5097 nodeA = link[ 'src' ][ 'device' ]
5098 nodeB = link[ 'dst' ][ 'device' ]
5099 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005100 if nodeA not in graphDict.keys():
5101 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005102 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005103 'type': idToDevice[ nodeA ][ 'type' ],
5104 'available': idToDevice[ nodeA ][ 'available' ],
5105 'role': idToDevice[ nodeA ][ 'role' ],
5106 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5107 'hw': idToDevice[ nodeA ][ 'hw' ],
5108 'sw': idToDevice[ nodeA ][ 'sw' ],
5109 'serial': idToDevice[ nodeA ][ 'serial' ],
5110 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005111 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005112 else:
5113 # Assert nodeB is not connected to any current links of nodeA
5114 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005115 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5116 'type': link[ 'type' ],
5117 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005118 return graphDict
5119 except ( TypeError, ValueError ):
5120 main.log.exception( self.name + ": Object not as expected" )
5121 return None
5122 except KeyError:
5123 main.log.exception( self.name + ": KeyError exception found" )
5124 return None
5125 except AssertionError:
5126 main.log.exception( self.name + ": AssertionError exception found" )
5127 return None
5128 except pexpect.EOF:
5129 main.log.error( self.name + ": EOF exception found" )
5130 main.log.error( self.name + ": " + self.handle.before )
5131 return None
5132 except Exception:
5133 main.log.exception( self.name + ": Uncaught exception!" )
5134 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005135
5136 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005137 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005138 Send command to check intent-perf summary
5139 Returns: dictionary for intent-perf summary
5140 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005141 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005142 cmd = "intent-perf -s"
5143 respDic = {}
5144 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005145 assert resp is not None, "Error in sendline"
5146 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005147 try:
5148 # Generate the dictionary to return
5149 for l in resp.split( "\n" ):
5150 # Delete any white space in line
5151 temp = re.sub( r'\s+', '', l )
5152 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005153 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005154
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005155 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005156 main.log.exception( self.name + ": Object not as expected" )
5157 return None
5158 except KeyError:
5159 main.log.exception( self.name + ": KeyError exception found" )
5160 return None
5161 except AssertionError:
5162 main.log.exception( self.name + ": AssertionError exception found" )
5163 return None
5164 except pexpect.EOF:
5165 main.log.error( self.name + ": EOF exception found" )
5166 main.log.error( self.name + ": " + self.handle.before )
5167 return None
5168 except Exception:
5169 main.log.exception( self.name + ": Uncaught exception!" )
5170 return None
5171 return respDic
5172
Chiyu Chengec63bde2016-11-17 18:11:36 -08005173 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005174 """
5175 Searches the latest ONOS log file for the given search term and
5176 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005177
chengchiyu08303a02016-09-08 17:40:26 -07005178 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005179 searchTerm:
5180 The string to grep from the ONOS log.
5181 startLine:
5182 The term that decides which line is the start to search the searchTerm in
5183 the karaf log. For now, startTerm only works in 'first' mode.
5184 logNum:
5185 In some extreme cases, one karaf log is not big enough to contain all the
5186 information.Because of this, search mutiply logs is necessary to capture
5187 the right result. logNum is the number of karaf logs that we need to search
5188 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005189 mode:
5190 all: return all the strings that contain the search term
5191 last: return the last string that contains the search term
5192 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005193 num: return the number of times that the searchTerm appears in the log
5194 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005195 """
5196 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005197 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005198 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005199 logPath = '/opt/onos/log/karaf.log.'
5200 logPaths = '/opt/onos/log/karaf.log'
5201 for i in range( 1, logNum ):
5202 logPaths = logPath + str( i ) + " " + logPaths
5203 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005204 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005205 # 100000000 is just a extreme large number to make sure this function can
5206 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005207 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005208 if mode == 'all':
5209 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005210 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005211 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005212 elif mode == 'first':
5213 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5214 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005215 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005216 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005217 return num
You Wang6d301d42017-04-21 10:49:33 -07005218 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005219 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005220 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005221 else:
5222 main.log.error( self.name + " unsupported mode" )
5223 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005224 before = self.sendline( cmd )
5225 before = before.splitlines()
5226 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005227 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005228 return returnLines
5229 except AssertionError:
5230 main.log.error( self.name + " searchTerm is not string type" )
5231 return None
5232 except pexpect.EOF:
5233 main.log.error( self.name + ": EOF exception found" )
5234 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005235 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005236 except pexpect.TIMEOUT:
5237 main.log.error( self.name + ": TIMEOUT exception found" )
5238 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005239 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005240 except Exception:
5241 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005242 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005243
5244 def vplsShow( self, jsonFormat=True ):
5245 """
5246 Description: Returns result of onos:vpls show, which should list the
5247 configured VPLS networks and the assigned interfaces.
5248 Optional:
5249 * jsonFormat: enable json formatting of output
5250 Returns:
5251 The output of the command or None on error.
5252 """
5253 try:
5254 cmdStr = "vpls show"
5255 if jsonFormat:
5256 raise NotImplementedError
5257 cmdStr += " -j"
5258 handle = self.sendline( cmdStr )
5259 assert handle is not None, "Error in sendline"
5260 assert "Command not found:" not in handle, handle
5261 return handle
5262 except AssertionError:
5263 main.log.exception( "" )
5264 return None
5265 except TypeError:
5266 main.log.exception( self.name + ": Object not as expected" )
5267 return None
5268 except pexpect.EOF:
5269 main.log.error( self.name + ": EOF exception found" )
5270 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005271 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005272 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005273 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005274 return None
5275 except Exception:
5276 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005277 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005278
5279 def parseVplsShow( self ):
5280 """
5281 Parse the cli output of 'vpls show' into json output. This is required
5282 as there is currently no json output available.
5283 """
5284 try:
5285 output = []
5286 raw = self.vplsShow( jsonFormat=False )
5287 namePat = "VPLS name: (?P<name>\w+)"
5288 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5289 encapPat = "Encapsulation: (?P<encap>\w+)"
5290 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5291 mIter = re.finditer( pattern, raw )
5292 for match in mIter:
5293 item = {}
5294 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005295 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005296 if ifaces == [ "" ]:
5297 ifaces = []
5298 item[ 'interfaces' ] = ifaces
5299 encap = match.group( 'encap' )
5300 if encap != 'NONE':
5301 item[ 'encapsulation' ] = encap.lower()
5302 output.append( item )
5303 return output
5304 except Exception:
5305 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005306 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005307
5308 def vplsList( self, jsonFormat=True ):
5309 """
5310 Description: Returns result of onos:vpls list, which should list the
5311 configured VPLS networks.
5312 Optional:
5313 * jsonFormat: enable json formatting of output
5314 """
5315 try:
5316 cmdStr = "vpls list"
5317 if jsonFormat:
5318 raise NotImplementedError
5319 cmdStr += " -j"
5320 handle = self.sendline( cmdStr )
5321 assert handle is not None, "Error in sendline"
5322 assert "Command not found:" not in handle, handle
5323 return handle
5324 except AssertionError:
5325 main.log.exception( "" )
5326 return None
5327 except TypeError:
5328 main.log.exception( self.name + ": Object not as expected" )
5329 return None
5330 except pexpect.EOF:
5331 main.log.error( self.name + ": EOF exception found" )
5332 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005333 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005334 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005335 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005336 return None
5337 except Exception:
5338 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005339 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005340
5341 def vplsCreate( self, network ):
5342 """
5343 CLI command to create a new VPLS network.
5344 Required arguments:
5345 network - String name of the network to create.
5346 returns:
5347 main.TRUE on success and main.FALSE on failure
5348 """
5349 try:
5350 network = str( network )
5351 cmdStr = "vpls create "
5352 cmdStr += network
5353 output = self.sendline( cmdStr )
5354 assert output is not None, "Error in sendline"
5355 assert "Command not found:" not in output, output
5356 assert "Error executing command" not in output, output
5357 assert "VPLS already exists:" not in output, output
5358 return main.TRUE
5359 except AssertionError:
5360 main.log.exception( "" )
5361 return main.FALSE
5362 except TypeError:
5363 main.log.exception( self.name + ": Object not as expected" )
5364 return main.FALSE
5365 except pexpect.EOF:
5366 main.log.error( self.name + ": EOF exception found" )
5367 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005368 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005369 except Exception:
5370 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005371 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005372
5373 def vplsDelete( self, network ):
5374 """
5375 CLI command to delete a VPLS network.
5376 Required arguments:
5377 network - Name of the network to delete.
5378 returns:
5379 main.TRUE on success and main.FALSE on failure
5380 """
5381 try:
5382 network = str( network )
5383 cmdStr = "vpls delete "
5384 cmdStr += network
5385 output = self.sendline( cmdStr )
5386 assert output is not None, "Error in sendline"
5387 assert "Command not found:" not in output, output
5388 assert "Error executing command" not in output, output
5389 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005390 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005391 return main.TRUE
5392 except AssertionError:
5393 main.log.exception( "" )
5394 return main.FALSE
5395 except TypeError:
5396 main.log.exception( self.name + ": Object not as expected" )
5397 return main.FALSE
5398 except pexpect.EOF:
5399 main.log.error( self.name + ": EOF exception found" )
5400 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005401 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005402 except Exception:
5403 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005404 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005405
5406 def vplsAddIface( self, network, iface ):
5407 """
5408 CLI command to add an interface to a VPLS network.
5409 Required arguments:
5410 network - Name of the network to add the interface to.
5411 iface - The ONOS name for an interface.
5412 returns:
5413 main.TRUE on success and main.FALSE on failure
5414 """
5415 try:
5416 network = str( network )
5417 iface = str( iface )
5418 cmdStr = "vpls add-if "
5419 cmdStr += network + " " + iface
5420 output = self.sendline( cmdStr )
5421 assert output is not None, "Error in sendline"
5422 assert "Command not found:" not in output, output
5423 assert "Error executing command" not in output, output
5424 assert "already associated to network" not in output, output
5425 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005426 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005427 return main.TRUE
5428 except AssertionError:
5429 main.log.exception( "" )
5430 return main.FALSE
5431 except TypeError:
5432 main.log.exception( self.name + ": Object not as expected" )
5433 return main.FALSE
5434 except pexpect.EOF:
5435 main.log.error( self.name + ": EOF exception found" )
5436 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005437 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005438 except Exception:
5439 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005440 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005441
5442 def vplsRemIface( self, network, iface ):
5443 """
5444 CLI command to remove an interface from a VPLS network.
5445 Required arguments:
5446 network - Name of the network to remove the interface from.
5447 iface - Name of the interface to remove.
5448 returns:
5449 main.TRUE on success and main.FALSE on failure
5450 """
5451 try:
5452 iface = str( iface )
5453 cmdStr = "vpls rem-if "
5454 cmdStr += network + " " + iface
5455 output = self.sendline( cmdStr )
5456 assert output is not None, "Error in sendline"
5457 assert "Command not found:" not in output, output
5458 assert "Error executing command" not in output, output
5459 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005460 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005461 return main.TRUE
5462 except AssertionError:
5463 main.log.exception( "" )
5464 return main.FALSE
5465 except TypeError:
5466 main.log.exception( self.name + ": Object not as expected" )
5467 return main.FALSE
5468 except pexpect.EOF:
5469 main.log.error( self.name + ": EOF exception found" )
5470 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005471 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005472 except Exception:
5473 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005474 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005475
5476 def vplsClean( self ):
5477 """
5478 Description: Clears the VPLS app configuration.
5479 Returns: main.TRUE on success and main.FALSE on failure
5480 """
5481 try:
5482 cmdStr = "vpls clean"
5483 handle = self.sendline( cmdStr )
5484 assert handle is not None, "Error in sendline"
5485 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005486 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005487 return handle
5488 except AssertionError:
5489 main.log.exception( "" )
5490 return main.FALSE
5491 except TypeError:
5492 main.log.exception( self.name + ": Object not as expected" )
5493 return main.FALSE
5494 except pexpect.EOF:
5495 main.log.error( self.name + ": EOF exception found" )
5496 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005497 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005498 except Exception:
5499 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005500 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005501
5502 def vplsSetEncap( self, network, encapType ):
5503 """
5504 CLI command to add an interface to a VPLS network.
5505 Required arguments:
5506 network - Name of the network to create.
5507 encapType - Type of encapsulation.
5508 returns:
5509 main.TRUE on success and main.FALSE on failure
5510 """
5511 try:
5512 network = str( network )
5513 encapType = str( encapType ).upper()
5514 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5515 cmdStr = "vpls set-encap "
5516 cmdStr += network + " " + encapType
5517 output = self.sendline( cmdStr )
5518 assert output is not None, "Error in sendline"
5519 assert "Command not found:" not in output, output
5520 assert "Error executing command" not in output, output
5521 assert "already associated to network" not in output, output
5522 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005523 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005524 return main.TRUE
5525 except AssertionError:
5526 main.log.exception( "" )
5527 return main.FALSE
5528 except TypeError:
5529 main.log.exception( self.name + ": Object not as expected" )
5530 return main.FALSE
5531 except pexpect.EOF:
5532 main.log.error( self.name + ": EOF exception found" )
5533 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005534 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005535 except Exception:
5536 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005537 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005538
5539 def interfaces( self, jsonFormat=True ):
5540 """
5541 Description: Returns result of interfaces command.
5542 Optional:
5543 * jsonFormat: enable json formatting of output
5544 Returns:
5545 The output of the command or None on error.
5546 """
5547 try:
5548 cmdStr = "interfaces"
5549 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005550 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005551 cmdStr += " -j"
5552 handle = self.sendline( cmdStr )
5553 assert handle is not None, "Error in sendline"
5554 assert "Command not found:" not in handle, handle
5555 return handle
5556 except AssertionError:
5557 main.log.exception( "" )
5558 return None
5559 except TypeError:
5560 main.log.exception( self.name + ": Object not as expected" )
5561 return None
5562 except pexpect.EOF:
5563 main.log.error( self.name + ": EOF exception found" )
5564 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005565 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005566 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005567 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005568 return None
5569 except Exception:
5570 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005571 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005572
5573 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005574 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005575 Get the timestamp of searchTerm from karaf log.
5576
5577 Arguments:
5578 splitTerm_before and splitTerm_after:
5579
5580 The terms that split the string that contains the timeStamp of
5581 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5582 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5583 and the splitTerm_after is "x"
5584
5585 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005586 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005587 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005588 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005589 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005590 return main.ERROR
5591 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005592 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005593 main.log.warn( "Captured timestamp string is empty" )
5594 return main.ERROR
5595 lines = lines[ 0 ]
5596 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005597 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005598 # get the target value
5599 line = lines.split( splitTerm_before )
5600 key = line[ 1 ].split( splitTerm_after )
5601 return int( key[ 0 ] )
5602 except IndexError:
5603 main.log.warn( "Index Error!" )
5604 return main.ERROR
5605 except AssertionError:
5606 main.log.warn( "Search Term Not Found " )
5607 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005608
5609 def workQueueAdd( self, queueName, value ):
5610 """
5611 CLI command to add a string to the specified Work Queue.
5612 This function uses the distributed primitives test app, which
5613 gives some cli access to distributed primitives for testing
5614 purposes only.
5615
5616 Required arguments:
5617 queueName - The name of the queue to add to
5618 value - The value to add to the queue
5619 returns:
5620 main.TRUE on success, main.FALSE on failure and
5621 main.ERROR on error.
5622 """
5623 try:
5624 queueName = str( queueName )
5625 value = str( value )
5626 prefix = "work-queue-test"
5627 operation = "add"
5628 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5629 output = self.distPrimitivesSend( cmdStr )
5630 if "Invalid operation name" in output:
5631 main.log.warn( output )
5632 return main.ERROR
5633 elif "Done" in output:
5634 return main.TRUE
5635 except TypeError:
5636 main.log.exception( self.name + ": Object not as expected" )
5637 return main.ERROR
5638 except Exception:
5639 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005640 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005641
5642 def workQueueAddMultiple( self, queueName, value1, value2 ):
5643 """
5644 CLI command to add two strings to the specified Work Queue.
5645 This function uses the distributed primitives test app, which
5646 gives some cli access to distributed primitives for testing
5647 purposes only.
5648
5649 Required arguments:
5650 queueName - The name of the queue to add to
5651 value1 - The first value to add to the queue
5652 value2 - The second value to add to the queue
5653 returns:
5654 main.TRUE on success, main.FALSE on failure and
5655 main.ERROR on error.
5656 """
5657 try:
5658 queueName = str( queueName )
5659 value1 = str( value1 )
5660 value2 = str( value2 )
5661 prefix = "work-queue-test"
5662 operation = "addMultiple"
5663 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5664 output = self.distPrimitivesSend( cmdStr )
5665 if "Invalid operation name" in output:
5666 main.log.warn( output )
5667 return main.ERROR
5668 elif "Done" in output:
5669 return main.TRUE
5670 except TypeError:
5671 main.log.exception( self.name + ": Object not as expected" )
5672 return main.ERROR
5673 except Exception:
5674 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005675 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005676
5677 def workQueueTakeAndComplete( self, queueName, number=1 ):
5678 """
5679 CLI command to take a value from the specified Work Queue and compelte it.
5680 This function uses the distributed primitives test app, which
5681 gives some cli access to distributed primitives for testing
5682 purposes only.
5683
5684 Required arguments:
5685 queueName - The name of the queue to add to
5686 number - The number of items to take and complete
5687 returns:
5688 main.TRUE on success, main.FALSE on failure and
5689 main.ERROR on error.
5690 """
5691 try:
5692 queueName = str( queueName )
5693 number = str( int( number ) )
5694 prefix = "work-queue-test"
5695 operation = "takeAndComplete"
5696 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5697 output = self.distPrimitivesSend( cmdStr )
5698 if "Invalid operation name" in output:
5699 main.log.warn( output )
5700 return main.ERROR
5701 elif "Done" in output:
5702 return main.TRUE
5703 except TypeError:
5704 main.log.exception( self.name + ": Object not as expected" )
5705 return main.ERROR
5706 except Exception:
5707 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005708 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005709
5710 def workQueueDestroy( self, queueName ):
5711 """
5712 CLI command to destroy the specified Work Queue.
5713 This function uses the distributed primitives test app, which
5714 gives some cli access to distributed primitives for testing
5715 purposes only.
5716
5717 Required arguments:
5718 queueName - The name of the queue to add to
5719 returns:
5720 main.TRUE on success, main.FALSE on failure and
5721 main.ERROR on error.
5722 """
5723 try:
5724 queueName = str( queueName )
5725 prefix = "work-queue-test"
5726 operation = "destroy"
5727 cmdStr = " ".join( [ prefix, queueName, operation ] )
5728 output = self.distPrimitivesSend( cmdStr )
5729 if "Invalid operation name" in output:
5730 main.log.warn( output )
5731 return main.ERROR
5732 return main.TRUE
5733 except TypeError:
5734 main.log.exception( self.name + ": Object not as expected" )
5735 return main.ERROR
5736 except Exception:
5737 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005738 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005739
5740 def workQueueTotalPending( self, queueName ):
5741 """
5742 CLI command to get the Total Pending items of the specified Work Queue.
5743 This function uses the distributed primitives test app, which
5744 gives some cli access to distributed primitives for testing
5745 purposes only.
5746
5747 Required arguments:
5748 queueName - The name of the queue to add to
5749 returns:
5750 The number of Pending items in the specified work queue or
5751 None on error
5752 """
5753 try:
5754 queueName = str( queueName )
5755 prefix = "work-queue-test"
5756 operation = "totalPending"
5757 cmdStr = " ".join( [ prefix, queueName, operation ] )
5758 output = self.distPrimitivesSend( cmdStr )
5759 pattern = r'\d+'
5760 if "Invalid operation name" in output:
5761 main.log.warn( output )
5762 return None
5763 else:
5764 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005765 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005766 except ( AttributeError, TypeError ):
5767 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5768 return None
5769 except Exception:
5770 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005771 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005772
5773 def workQueueTotalCompleted( self, queueName ):
5774 """
5775 CLI command to get the Total Completed items of the specified Work Queue.
5776 This function uses the distributed primitives test app, which
5777 gives some cli access to distributed primitives for testing
5778 purposes only.
5779
5780 Required arguments:
5781 queueName - The name of the queue to add to
5782 returns:
5783 The number of complete items in the specified work queue or
5784 None on error
5785 """
5786 try:
5787 queueName = str( queueName )
5788 prefix = "work-queue-test"
5789 operation = "totalCompleted"
5790 cmdStr = " ".join( [ prefix, queueName, operation ] )
5791 output = self.distPrimitivesSend( cmdStr )
5792 pattern = r'\d+'
5793 if "Invalid operation name" in output:
5794 main.log.warn( output )
5795 return None
5796 else:
5797 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005798 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005799 except ( AttributeError, TypeError ):
5800 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5801 return None
5802 except Exception:
5803 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005804 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005805
5806 def workQueueTotalInProgress( self, queueName ):
5807 """
5808 CLI command to get the Total In Progress items of the specified Work Queue.
5809 This function uses the distributed primitives test app, which
5810 gives some cli access to distributed primitives for testing
5811 purposes only.
5812
5813 Required arguments:
5814 queueName - The name of the queue to add to
5815 returns:
5816 The number of In Progress items in the specified work queue or
5817 None on error
5818 """
5819 try:
5820 queueName = str( queueName )
5821 prefix = "work-queue-test"
5822 operation = "totalInProgress"
5823 cmdStr = " ".join( [ prefix, queueName, operation ] )
5824 output = self.distPrimitivesSend( cmdStr )
5825 pattern = r'\d+'
5826 if "Invalid operation name" in output:
5827 main.log.warn( output )
5828 return None
5829 else:
5830 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005831 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005832 except ( AttributeError, TypeError ):
5833 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5834 return None
5835 except Exception:
5836 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005837 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005838
5839 def events( self, args='-a' ):
5840 """
5841 Description: Returns events -a command output
5842 Optional:
5843 add other arguments
5844 """
5845 try:
5846 cmdStr = "events"
5847 if args:
5848 cmdStr += " " + args
5849 handle = self.sendline( cmdStr )
5850 assert handle is not None, "Error in sendline"
5851 assert "Command not found:" not in handle, handle
5852 return handle
5853 except AssertionError:
5854 main.log.exception( "" )
5855 return None
5856 except TypeError:
5857 main.log.exception( self.name + ": Object not as expected" )
5858 return None
5859 except pexpect.EOF:
5860 main.log.error( self.name + ": EOF exception found" )
5861 main.log.error( self.name + ": " + self.handle.before )
5862 main.cleanAndExit()
5863 except Exception:
5864 main.log.exception( self.name + ": Uncaught exception!" )
5865 main.cleanAndExit()
5866
5867 def getMaster( self, deviceID ):
5868 """
5869 Description: Obtains current master using "roles" command for a specific deviceID
5870 """
5871 try:
5872 return str( self.getRole( deviceID )[ 'master' ] )
5873 except AssertionError:
5874 main.log.exception( "" )
5875 return None
5876 except TypeError:
5877 main.log.exception( self.name + ": Object not as expected" )
5878 return None
5879 except pexpect.EOF:
5880 main.log.error( self.name + ": EOF exception found" )
5881 main.log.error( self.name + ": " + self.handle.before )
5882 main.cleanAndExit()
5883 except Exception:
5884 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07005885 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08005886
5887 def issu( self ):
5888 """
5889 Short summary of In-Service Software Upgrade status
5890
5891 Returns the output of the cli command or None on Error
5892 """
5893 try:
5894 cmdStr = "issu"
5895 handle = self.sendline( cmdStr )
5896 assert handle is not None, "Error in sendline"
5897 assert "Command not found:" not in handle, handle
5898 assert "Unsupported command:" not in handle, handle
5899 return handle
5900 except AssertionError:
5901 main.log.exception( "" )
5902 return None
5903 except TypeError:
5904 main.log.exception( self.name + ": Object not as expected" )
5905 return None
5906 except pexpect.EOF:
5907 main.log.error( self.name + ": EOF exception found" )
5908 main.log.error( self.name + ": " + self.handle.before )
5909 main.cleanAndExit()
5910 except Exception:
5911 main.log.exception( self.name + ": Uncaught exception!" )
5912 main.cleanAndExit()
5913
5914 def issuInit( self ):
5915 """
5916 Initiates an In-Service Software Upgrade
5917
5918 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5919 """
5920 try:
5921 cmdStr = "issu init"
5922 handle = self.sendline( cmdStr )
5923 assert handle is not None, "Error in sendline"
5924 assert "Command not found:" not in handle, handle
5925 assert "Unsupported command:" not in handle, handle
5926 if "Initialized" in handle:
5927 return main.TRUE
5928 else:
5929 return main.FALSE
5930 except AssertionError:
5931 main.log.exception( "" )
5932 return main.ERROR
5933 except TypeError:
5934 main.log.exception( self.name + ": Object not as expected" )
5935 return main.ERROR
5936 except pexpect.EOF:
5937 main.log.error( self.name + ": EOF exception found" )
5938 main.log.error( self.name + ": " + self.handle.before )
5939 main.cleanAndExit()
5940 except Exception:
5941 main.log.exception( self.name + ": Uncaught exception!" )
5942 main.cleanAndExit()
5943
5944 def issuUpgrade( self ):
5945 """
5946 Transitions stores to upgraded nodes
5947
5948 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5949 """
5950 try:
5951 cmdStr = "issu upgrade"
5952 handle = self.sendline( cmdStr )
5953 assert handle is not None, "Error in sendline"
5954 assert "Command not found:" not in handle, handle
5955 assert "Unsupported command:" not in handle, handle
5956 if "Upgraded" in handle:
5957 return main.TRUE
5958 else:
5959 return main.FALSE
5960 except AssertionError:
5961 main.log.exception( "" )
5962 return main.ERROR
5963 except TypeError:
5964 main.log.exception( self.name + ": Object not as expected" )
5965 return main.ERROR
5966 except pexpect.EOF:
5967 main.log.error( self.name + ": EOF exception found" )
5968 main.log.error( self.name + ": " + self.handle.before )
5969 main.cleanAndExit()
5970 except Exception:
5971 main.log.exception( self.name + ": Uncaught exception!" )
5972 main.cleanAndExit()
5973
5974 def issuCommit( self ):
5975 """
5976 Finalizes an In-Service Software Upgrade
5977
5978 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5979 """
5980 try:
5981 cmdStr = "issu commit"
5982 handle = self.sendline( cmdStr )
5983 assert handle is not None, "Error in sendline"
5984 assert "Command not found:" not in handle, handle
5985 assert "Unsupported command:" not in handle, handle
5986 # TODO: Check the version returned by this command
5987 if "Committed version" in handle:
5988 return main.TRUE
5989 else:
5990 return main.FALSE
5991 except AssertionError:
5992 main.log.exception( "" )
5993 return main.ERROR
5994 except TypeError:
5995 main.log.exception( self.name + ": Object not as expected" )
5996 return main.ERROR
5997 except pexpect.EOF:
5998 main.log.error( self.name + ": EOF exception found" )
5999 main.log.error( self.name + ": " + self.handle.before )
6000 main.cleanAndExit()
6001 except Exception:
6002 main.log.exception( self.name + ": Uncaught exception!" )
6003 main.cleanAndExit()
6004
6005 def issuRollback( self ):
6006 """
6007 Rolls back an In-Service Software Upgrade
6008
6009 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6010 """
6011 try:
6012 cmdStr = "issu rollback"
6013 handle = self.sendline( cmdStr )
6014 assert handle is not None, "Error in sendline"
6015 assert "Command not found:" not in handle, handle
6016 assert "Unsupported command:" not in handle, handle
6017 # TODO: Check the version returned by this command
6018 if "Rolled back to version" in handle:
6019 return main.TRUE
6020 else:
6021 return main.FALSE
6022 except AssertionError:
6023 main.log.exception( "" )
6024 return main.ERROR
6025 except TypeError:
6026 main.log.exception( self.name + ": Object not as expected" )
6027 return main.ERROR
6028 except pexpect.EOF:
6029 main.log.error( self.name + ": EOF exception found" )
6030 main.log.error( self.name + ": " + self.handle.before )
6031 main.cleanAndExit()
6032 except Exception:
6033 main.log.exception( self.name + ": Uncaught exception!" )
6034 main.cleanAndExit()
6035
6036 def issuReset( self ):
6037 """
6038 Resets the In-Service Software Upgrade status after a rollback
6039
6040 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6041 """
6042 try:
6043 cmdStr = "issu reset"
6044 handle = self.sendline( cmdStr )
6045 assert handle is not None, "Error in sendline"
6046 assert "Command not found:" not in handle, handle
6047 assert "Unsupported command:" not in handle, handle
6048 # TODO: Check the version returned by this command
6049 if "Reset version" in handle:
6050 return main.TRUE
6051 else:
6052 return main.FALSE
6053 except AssertionError:
6054 main.log.exception( "" )
6055 return main.ERROR
6056 except TypeError:
6057 main.log.exception( self.name + ": Object not as expected" )
6058 return main.ERROR
6059 except pexpect.EOF:
6060 main.log.error( self.name + ": EOF exception found" )
6061 main.log.error( self.name + ": " + self.handle.before )
6062 main.cleanAndExit()
6063 except Exception:
6064 main.log.exception( self.name + ": Uncaught exception!" )
6065 main.cleanAndExit()
6066
6067 def issuStatus( self ):
6068 """
6069 Status of an In-Service Software Upgrade
6070
6071 Returns the output of the cli command or None on Error
6072 """
6073 try:
6074 cmdStr = "issu status"
6075 handle = self.sendline( cmdStr )
6076 assert handle is not None, "Error in sendline"
6077 assert "Command not found:" not in handle, handle
6078 assert "Unsupported command:" not in handle, handle
6079 return handle
6080 except AssertionError:
6081 main.log.exception( "" )
6082 return None
6083 except TypeError:
6084 main.log.exception( self.name + ": Object not as expected" )
6085 return None
6086 except pexpect.EOF:
6087 main.log.error( self.name + ": EOF exception found" )
6088 main.log.error( self.name + ": " + self.handle.before )
6089 main.cleanAndExit()
6090 except Exception:
6091 main.log.exception( self.name + ": Uncaught exception!" )
6092 main.cleanAndExit()
6093
6094 def issuVersion( self ):
6095 """
6096 Get the version of an In-Service Software Upgrade
6097
6098 Returns the output of the cli command or None on Error
6099 """
6100 try:
6101 cmdStr = "issu version"
6102 handle = self.sendline( cmdStr )
6103 assert handle is not None, "Error in sendline"
6104 assert "Command not found:" not in handle, handle
6105 assert "Unsupported command:" not in handle, handle
6106 return handle
6107 except AssertionError:
6108 main.log.exception( "" )
6109 return None
6110 except TypeError:
6111 main.log.exception( self.name + ": Object not as expected" )
6112 return None
6113 except pexpect.EOF:
6114 main.log.error( self.name + ": EOF exception found" )
6115 main.log.error( self.name + ": " + self.handle.before )
6116 main.cleanAndExit()
6117 except Exception:
6118 main.log.exception( self.name + ": Uncaught exception!" )
6119 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006120
6121 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6122 """
6123 Create a multicast route by calling 'mcast-join' command
6124 sIP: source IP of the multicast route
6125 groupIP: group IP of the multicast route
6126 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6127 dPorts: a list of destination ports of the multicast route
6128 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6129 """
6130 try:
6131 cmdStr = "mcast-join"
6132 cmdStr += " " + str( sIP )
6133 cmdStr += " " + str( groupIP )
6134 cmdStr += " " + str( sPort )
6135 assert isinstance( dPorts, list )
6136 for dPort in dPorts:
6137 cmdStr += " " + str( dPort )
6138 handle = self.sendline( cmdStr )
6139 assert handle is not None, "Error in sendline"
6140 assert "Command not found:" not in handle, handle
6141 assert "Unsupported command:" not in handle, handle
6142 assert "Error executing command" not in handle, handle
6143 if "Added the mcast route" in handle:
6144 return main.TRUE
6145 else:
6146 return main.FALSE
6147 except AssertionError:
6148 main.log.exception( "" )
6149 return None
6150 except TypeError:
6151 main.log.exception( self.name + ": Object not as expected" )
6152 return None
6153 except pexpect.EOF:
6154 main.log.error( self.name + ": EOF exception found" )
6155 main.log.error( self.name + ": " + self.handle.before )
6156 main.cleanAndExit()
6157 except Exception:
6158 main.log.exception( self.name + ": Uncaught exception!" )
6159 main.cleanAndExit()
6160
6161 def mcastDelete( self, sIP, groupIP, dPorts ):
6162 """
6163 Delete a multicast route by calling 'mcast-delete' command
6164 sIP: source IP of the multicast route
6165 groupIP: group IP of the multicast route
6166 dPorts: a list of destination ports of the multicast route
6167 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6168 """
6169 try:
6170 cmdStr = "mcast-delete"
6171 cmdStr += " " + str( sIP )
6172 cmdStr += " " + str( groupIP )
6173 assert isinstance( dPorts, list )
6174 for dPort in dPorts:
6175 cmdStr += " " + str( dPort )
6176 handle = self.sendline( cmdStr )
6177 assert handle is not None, "Error in sendline"
6178 assert "Command not found:" not in handle, handle
6179 assert "Unsupported command:" not in handle, handle
6180 assert "Error executing command" not in handle, handle
6181 if "Updated the mcast route" in handle:
6182 return main.TRUE
6183 else:
6184 return main.FALSE
6185 except AssertionError:
6186 main.log.exception( "" )
6187 return None
6188 except TypeError:
6189 main.log.exception( self.name + ": Object not as expected" )
6190 return None
6191 except pexpect.EOF:
6192 main.log.error( self.name + ": EOF exception found" )
6193 main.log.error( self.name + ": " + self.handle.before )
6194 main.cleanAndExit()
6195 except Exception:
6196 main.log.exception( self.name + ": Uncaught exception!" )
6197 main.cleanAndExit()
6198
6199 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6200 """
6201 Create a multicast route by calling 'mcast-host-join' command
6202 sAddr: we can provide * for ASM or a specific address for SSM
6203 gAddr: specifies multicast group address
6204 srcs: a list of the source connect points e.g. ["of:0000000000000003/12"]
6205 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6206 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6207 """
6208 try:
6209 cmdStr = "mcast-host-join"
6210 cmdStr += " -sAddr " + str( sAddr )
6211 cmdStr += " -gAddr " + str( gAddr )
6212 assert isinstance( srcs, list )
6213 for src in srcs:
6214 cmdStr += " -srcs " + str( src )
6215 assert isinstance( sinks, list )
6216 for sink in sinks:
6217 cmdStr += " -sinks " + str( sink )
6218 handle = self.sendline( cmdStr )
6219 assert handle is not None, "Error in sendline"
6220 assert "Command not found:" not in handle, handle
6221 assert "Unsupported command:" not in handle, handle
6222 assert "Error executing command" not in handle, handle
6223 if "Added the mcast route" in handle:
6224 return main.TRUE
6225 else:
6226 return main.FALSE
6227 except AssertionError:
6228 main.log.exception( "" )
6229 return None
6230 except TypeError:
6231 main.log.exception( self.name + ": Object not as expected" )
6232 return None
6233 except pexpect.EOF:
6234 main.log.error( self.name + ": EOF exception found" )
6235 main.log.error( self.name + ": " + self.handle.before )
6236 main.cleanAndExit()
6237 except Exception:
6238 main.log.exception( self.name + ": Uncaught exception!" )
6239 main.cleanAndExit()
6240
6241 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6242 """
6243 Delete multicast sink(s) by calling 'mcast-host-delete' command
6244 sAddr: we can provide * for ASM or a specific address for SSM
6245 gAddr: specifies multicast group address
6246 hosts: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6247 will delete the route if not specified
6248 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6249 """
6250 try:
6251 cmdStr = "mcast-host-delete"
6252 cmdStr += " -sAddr " + str( sAddr )
6253 cmdStr += " -gAddr " + str( gAddr )
6254 if host:
6255 cmdStr += " -h " + str( host )
6256 handle = self.sendline( cmdStr )
6257 assert handle is not None, "Error in sendline"
6258 assert "Command not found:" not in handle, handle
6259 assert "Unsupported command:" not in handle, handle
6260 assert "Error executing command" not in handle, handle
6261 if "Updated the mcast route" in handle:
6262 return main.TRUE
6263 elif "Deleted the mcast route" in handle:
6264 return main.TRUE
6265 else:
6266 return main.FALSE
6267 except AssertionError:
6268 main.log.exception( "" )
6269 return None
6270 except TypeError:
6271 main.log.exception( self.name + ": Object not as expected" )
6272 return None
6273 except pexpect.EOF:
6274 main.log.error( self.name + ": EOF exception found" )
6275 main.log.error( self.name + ": " + self.handle.before )
6276 main.cleanAndExit()
6277 except Exception:
6278 main.log.exception( self.name + ": Uncaught exception!" )
6279 main.cleanAndExit()
6280
6281 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6282 """
6283 Delete multicast src(s) by calling 'mcast-source-delete' command
6284 sAddr: we can provide * for ASM or a specific address for SSM
6285 gAddr: specifies multicast group address
6286 srcs: a list of connect points of the sources e.g. ["00:AA:00:00:01:05/40"],
6287 will delete the route if not specified
6288 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6289 """
6290 try:
6291 cmdStr = "mcast-source-delete"
6292 cmdStr += " -sAddr " + str( sAddr )
6293 cmdStr += " -gAddr " + str( gAddr )
6294 if srcs:
6295 assert isinstance( srcs, list )
6296 for src in srcs:
6297 cmdStr += " -src " + str( src )
6298 handle = self.sendline( cmdStr )
6299 assert handle is not None, "Error in sendline"
6300 assert "Command not found:" not in handle, handle
6301 assert "Unsupported command:" not in handle, handle
6302 assert "Error executing command" not in handle, handle
6303 if "Updated the mcast route" in handle:
6304 return main.TRUE
6305 elif "Deleted the mcast route" in handle:
6306 return main.TRUE
6307 else:
6308 return main.FALSE
6309 except AssertionError:
6310 main.log.exception( "" )
6311 return None
6312 except TypeError:
6313 main.log.exception( self.name + ": Object not as expected" )
6314 return None
6315 except pexpect.EOF:
6316 main.log.error( self.name + ": EOF exception found" )
6317 main.log.error( self.name + ": " + self.handle.before )
6318 main.cleanAndExit()
6319 except Exception:
6320 main.log.exception( self.name + ": Uncaught exception!" )
6321 main.cleanAndExit()