blob: a15a96110385fe6302cc4e09a125f0f1031feebc [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
Jon Hall6c9e2da2018-11-06 12:01:23 -080061 self.karafPrompt = "sdn@root >" # FIXME: make configurable
You Wangdb8cd0a2016-05-26 15:19:45 -070062 self.graph = Graph()
Devin Limdc78e202017-06-09 18:30:07 -070063 super( OnosCliDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080064
Jeremy Ronquillo82705492017-10-18 14:19:55 -070065 def checkOptions( self, var, defaultVar ):
Devin Limdc78e202017-06-09 18:30:07 -070066 if var is None or var == "":
67 return defaultVar
68 return var
Jeremy Ronquillo82705492017-10-18 14:19:55 -070069
kelvin8ec71442015-01-15 16:57:00 -080070 def connect( self, **connectargs ):
71 """
andrewonlab95ce8322014-10-13 14:12:04 -040072 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080073 """
andrewonlab95ce8322014-10-13 14:12:04 -040074 try:
75 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080076 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070077 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040078 for key in self.options:
79 if key == "home":
Devin Limdc78e202017-06-09 18:30:07 -070080 self.home = self.options[ key ]
81 elif key == "karaf_username":
82 self.karafUser = self.options[ key ]
83 elif key == "karaf_password":
84 self.karafPass = self.options[ key ]
85
Jeremy Ronquillo82705492017-10-18 14:19:55 -070086 self.home = self.checkOptions( self.home, "~/onos" )
87 self.karafUser = self.checkOptions( self.karafUser, self.user_name )
88 self.karafPass = self.checkOptions( self.karafPass, self.pwd )
andrewonlab95ce8322014-10-13 14:12:04 -040089
kelvin-onlaba4074292015-07-09 15:19:49 -070090 for key in self.options:
91 if key == 'onosIp':
92 self.onosIp = self.options[ 'onosIp' ]
93 break
94
kelvin8ec71442015-01-15 16:57:00 -080095 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070096
97 try:
Jon Hallc6793552016-01-19 14:18:37 -080098 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070099 self.ip_address = os.getenv( str( self.ip_address ) )
100 else:
101 main.log.info( self.name +
102 ": Trying to connect to " +
103 self.ip_address )
104
105 except KeyError:
106 main.log.info( "Invalid host name," +
107 " connecting to local host instead" )
108 self.ip_address = 'localhost'
109 except Exception as inst:
110 main.log.error( "Uncaught exception: " + str( inst ) )
111
kelvin8ec71442015-01-15 16:57:00 -0800112 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800113 user_name=self.user_name,
114 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800115 port=self.port,
116 pwd=self.pwd,
117 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400118
kelvin8ec71442015-01-15 16:57:00 -0800119 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700120 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400121 if self.handle:
122 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800123 else:
124 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400125 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800126 except TypeError:
127 main.log.exception( self.name + ": Object not as expected" )
128 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400129 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800130 main.log.error( self.name + ": EOF exception found" )
131 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700132 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800133 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800134 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700135 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400136
kelvin8ec71442015-01-15 16:57:00 -0800137 def disconnect( self ):
138 """
andrewonlab95ce8322014-10-13 14:12:04 -0400139 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800140 """
Jon Halld61331b2015-02-17 16:35:47 -0800141 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400142 try:
Jon Hall61282e32015-03-19 11:34:11 -0700143 if self.handle:
144 i = self.logout()
145 if i == main.TRUE:
146 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700147 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700148 self.handle.sendline( "exit" )
149 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800150 except TypeError:
151 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800152 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400153 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800154 main.log.error( self.name + ": EOF exception found" )
155 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700156 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700157 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700158 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800159 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800160 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400161 response = main.FALSE
162 return response
163
kelvin8ec71442015-01-15 16:57:00 -0800164 def logout( self ):
165 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500166 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700167 Returns main.TRUE if exited CLI and
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000168 main.FALSE on timeout (not guranteed you are disconnected)
Jon Hall61282e32015-03-19 11:34:11 -0700169 None on TypeError
170 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800171 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500172 try:
Jon Hall61282e32015-03-19 11:34:11 -0700173 if self.handle:
174 self.handle.sendline( "" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800175 i = self.handle.expect( [ self.karafPrompt, self.prompt, pexpect.TIMEOUT ],
Jon Hall61282e32015-03-19 11:34:11 -0700176 timeout=10 )
177 if i == 0: # In ONOS CLI
178 self.handle.sendline( "logout" )
Devin Limdc78e202017-06-09 18:30:07 -0700179 j = self.handle.expect( [ self.prompt,
Jon Hallbfe00002016-04-05 10:23:54 -0700180 "Command not found:",
181 pexpect.TIMEOUT ] )
182 if j == 0: # Successfully logged out
183 return main.TRUE
184 elif j == 1 or j == 2:
185 # ONOS didn't fully load, and logout command isn't working
186 # or the command timed out
187 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700188 try:
Devin Limdc78e202017-06-09 18:30:07 -0700189 self.handle.expect( self.prompt )
Jon Hall64ab3bd2016-05-13 11:29:44 -0700190 except pexpect.TIMEOUT:
191 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700192 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700193 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700194 main.log.warn( "Unknown repsonse to logout command: '{}'",
195 repr( self.handle.before ) )
196 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700197 elif i == 1: # not in CLI
198 return main.TRUE
199 elif i == 3: # Timeout
200 return main.FALSE
201 else:
andrewonlab9627f432014-11-14 12:45:10 -0500202 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800203 except TypeError:
204 main.log.exception( self.name + ": Object not as expected" )
205 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500206 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800207 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700208 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700209 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700210 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700211 main.log.error( self.name +
212 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800213 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800214 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700215 main.cleanAndExit()
andrewonlab38d2b4a2014-11-13 16:28:47 -0500216
kelvin-onlabd3b64892015-01-20 13:26:24 -0800217 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800218 """
andrewonlab95ce8322014-10-13 14:12:04 -0400219 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800220
andrewonlab95ce8322014-10-13 14:12:04 -0400221 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800222 """
andrewonlab95ce8322014-10-13 14:12:04 -0400223 try:
224 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800225 main.log.error( "Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700226 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400227 else:
kelvin8ec71442015-01-15 16:57:00 -0800228 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800229 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800230 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400231 # and that this driver will have to change accordingly
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700232 self.handle.expect( str( cellname ) )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800233 handleBefore = self.handle.before
234 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800235 # Get the rest of the handle
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700236 self.handle.sendline( "" )
237 self.handle.expect( self.prompt )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800238 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400239
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 main.log.info( "Cell call returned: " + handleBefore +
241 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400242
243 return main.TRUE
244
Jon Halld4d4b372015-01-28 16:02:41 -0800245 except TypeError:
246 main.log.exception( self.name + ": Object not as expected" )
247 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400248 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800249 main.log.error( self.name + ": eof exception found" )
250 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700251 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800252 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800253 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700254 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -0800255
pingping-lin57a56ce2015-05-20 16:43:48 -0700256 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800257 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800258 """
Jon Hallefbd9792015-03-05 16:11:36 -0800259 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800260 by user would be used to set the current karaf shell idle timeout.
261 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800262 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800263 Below is an example to start a session with 60 seconds idle timeout
264 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800265
Hari Krishna25d42f72015-01-05 15:08:28 -0800266 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800268
kelvin-onlabd3b64892015-01-20 13:26:24 -0800269 Note: karafTimeout is left as str so that this could be read
270 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800271 """
You Wangf69ab392016-01-26 16:34:38 -0800272 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400273 try:
Jon Hall67253832016-12-05 09:47:13 -0800274 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800275 self.handle.sendline( "" )
276 x = self.handle.expect( [
Jon Hall6c9e2da2018-11-06 12:01:23 -0800277 self.prompt, self.karafPrompt ], commandlineTimeout )
andrewonlab48829f62014-11-17 13:49:01 -0500278 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800279 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500280 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400281
Jon Hall67253832016-12-05 09:47:13 -0800282 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800283 if waitForStart:
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800284 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
285 startCliCommand = "onos-wait-for-start "
Chiyu Chengef109502016-11-21 15:51:38 -0800286 else:
287 startCliCommand = "onos "
288 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800289 i = self.handle.expect( [
Jon Hall6c9e2da2018-11-06 12:01:23 -0800290 self.karafPrompt,
pingping-lin57a56ce2015-05-20 16:43:48 -0700291 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400292
293 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800294 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800295 if karafTimeout: # FIXME: This doesn't look right
kelvin8ec71442015-01-15 16:57:00 -0800296 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800297 "config:property-set -p org.apache.karaf.shell\
298 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800299 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700300 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800301 self.handle.sendline( startCliCommand + str( ONOSIp ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800302 self.handle.expect( self.karafPrompt )
303 main.log.debug( self.handle.before )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400304 return main.TRUE
305 else:
kelvin8ec71442015-01-15 16:57:00 -0800306 # If failed, send ctrl+c to process and try again
307 main.log.info( "Starting CLI failed. Retrying..." )
308 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800309 self.handle.sendline( startCliCommand + str( ONOSIp ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800310 i = self.handle.expect( [ self.karafPrompt, pexpect.TIMEOUT ],
kelvin8ec71442015-01-15 16:57:00 -0800311 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400312 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800313 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800314 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800315 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800316 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800317 "config:property-set -p org.apache.karaf.shell\
318 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800319 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700320 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800321 self.handle.sendline( startCliCommand + str( ONOSIp ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800322 self.handle.expect( self.karafPrompt )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400323 return main.TRUE
324 else:
kelvin8ec71442015-01-15 16:57:00 -0800325 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800326 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400327 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400328
Jon Halld4d4b372015-01-28 16:02:41 -0800329 except TypeError:
330 main.log.exception( self.name + ": Object not as expected" )
331 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400332 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800333 main.log.error( self.name + ": EOF exception found" )
334 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700335 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800336 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800337 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700338 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400339
suibin zhang116647a2016-05-06 16:30:09 -0700340 def startCellCli( self, karafTimeout="",
341 commandlineTimeout=10, onosStartTimeout=60 ):
342 """
343 Start CLI on onos ecll handle.
344
345 karafTimeout is an optional argument. karafTimeout value passed
346 by user would be used to set the current karaf shell idle timeout.
347 Note that when ever this property is modified the shell will exit and
348 the subsequent login would reflect new idle timeout.
349 Below is an example to start a session with 60 seconds idle timeout
350 ( input value is in milliseconds ):
351
352 tValue = "60000"
353
354 Note: karafTimeout is left as str so that this could be read
355 and passed to startOnosCli from PARAMS file as str.
356 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000357
suibin zhang116647a2016-05-06 16:30:09 -0700358 try:
359 self.handle.sendline( "" )
360 x = self.handle.expect( [
Jon Hall6c9e2da2018-11-06 12:01:23 -0800361 self.prompt, self.karafPrompt ], commandlineTimeout )
suibin zhang116647a2016-05-06 16:30:09 -0700362
363 if x == 1:
364 main.log.info( "ONOS cli is already running" )
365 return main.TRUE
366
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800367 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
suibin zhang116647a2016-05-06 16:30:09 -0700368 self.handle.sendline( "/opt/onos/bin/onos" )
369 i = self.handle.expect( [
Jon Hall6c9e2da2018-11-06 12:01:23 -0800370 self.karafPrompt,
suibin zhang116647a2016-05-06 16:30:09 -0700371 pexpect.TIMEOUT ], onosStartTimeout )
372
373 if i == 0:
374 main.log.info( self.name + " CLI Started successfully" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800375 if karafTimeout: # FIXME: This doesn't look right
suibin zhang116647a2016-05-06 16:30:09 -0700376 self.handle.sendline(
377 "config:property-set -p org.apache.karaf.shell\
378 sshIdleTimeout " +
379 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700380 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700381 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800382 self.handle.expect( self.karafPrompt )
383 main.log.debug( self.handle.before )
suibin zhang116647a2016-05-06 16:30:09 -0700384 return main.TRUE
385 else:
386 # If failed, send ctrl+c to process and try again
387 main.log.info( "Starting CLI failed. Retrying..." )
388 self.handle.send( "\x03" )
389 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800390 i = self.handle.expect( [ self.karafPrompt, pexpect.TIMEOUT ],
suibin zhang116647a2016-05-06 16:30:09 -0700391 timeout=30 )
392 if i == 0:
393 main.log.info( self.name + " CLI Started " +
394 "successfully after retry attempt" )
395 if karafTimeout:
396 self.handle.sendline(
397 "config:property-set -p org.apache.karaf.shell\
398 sshIdleTimeout " +
399 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700400 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700401 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800402 self.handle.expect( self.karafPrompt )
suibin zhang116647a2016-05-06 16:30:09 -0700403 return main.TRUE
404 else:
405 main.log.error( "Connection to CLI " +
406 self.name + " timeout" )
407 return main.FALSE
408
409 except TypeError:
410 main.log.exception( self.name + ": Object not as expected" )
411 return None
412 except pexpect.EOF:
413 main.log.error( self.name + ": EOF exception found" )
414 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700415 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700416 except Exception:
417 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700418 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700419
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800420 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800421 """
422 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800423 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800424 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700425 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800426 Available level: DEBUG, TRACE, INFO, WARN, ERROR
427 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800428 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800429 """
430 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800431 lvlStr = ""
432 if level:
433 lvlStr = "--level=" + level
434
kelvin-onlab338f5512015-02-06 10:53:16 -0800435 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700436 self.handle.expect( "log:log" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800437 self.handle.expect( self.karafPrompt )
kelvin-onlabfb521662015-02-27 09:52:40 -0800438
kelvin-onlab9f541032015-02-04 16:19:53 -0800439 response = self.handle.before
440 if re.search( "Error", response ):
441 return main.FALSE
442 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700443 except pexpect.TIMEOUT:
444 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700445 if noExit:
446 main.cleanup()
447 return None
448 else:
Devin Lim44075962017-08-11 10:56:37 -0700449 main.cleanAndExit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800450 except pexpect.EOF:
451 main.log.error( self.name + ": EOF exception found" )
452 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700453 if noExit:
454 main.cleanup()
455 return None
456 else:
Devin Lim44075962017-08-11 10:56:37 -0700457 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800458 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800459 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700460 if noExit:
461 main.cleanup()
462 return None
463 else:
Devin Lim44075962017-08-11 10:56:37 -0700464 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400465
Jon Hall0e240372018-05-02 11:21:57 -0700466 def clearBuffer( self, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800467 """
Jon Hall0e240372018-05-02 11:21:57 -0700468 Test cli connection and clear any left over output in the buffer
469 Optional Arguments:
470 debug - Defaults to False. If True, will enable debug logging.
471 timeout - Defaults to 10. Amount of time in seconds for a command to return
472 before a timeout.
473 noExit - Defaults to False. If True, will not exit TestON in the event of a
kelvin8ec71442015-01-15 16:57:00 -0800474 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400475 try:
Jon Halla495f562016-05-16 18:03:26 -0700476 # Try to reconnect if disconnected from cli
477 self.handle.sendline( "" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800478 i = self.handle.expect( [ self.karafPrompt, self.prompt, pexpect.TIMEOUT ] )
Jon Hall0e240372018-05-02 11:21:57 -0700479 response = self.handle.before
Jon Halla495f562016-05-16 18:03:26 -0700480 if i == 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700481 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700482 if self.onosIp:
483 main.log.warn( "Trying to reconnect " + self.onosIp )
484 reconnectResult = self.startOnosCli( self.onosIp )
485 if reconnectResult:
486 main.log.info( self.name + ": onos cli session reconnected." )
487 else:
488 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700489 if noExit:
490 return None
491 else:
Devin Lim44075962017-08-11 10:56:37 -0700492 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700493 else:
Devin Lim44075962017-08-11 10:56:37 -0700494 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700495 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700496 main.log.warn( "Timeout when testing cli responsiveness" )
497 main.log.debug( self.handle.before )
498 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Hall6c9e2da2018-11-06 12:01:23 -0800499 self.handle.expect( self.karafPrompt )
Jon Halla495f562016-05-16 18:03:26 -0700500
Jon Hall0e240372018-05-02 11:21:57 -0700501 response += self.handle.before
Jon Hall14a03b52016-05-11 12:07:30 -0700502 if debug:
Jon Hall0e240372018-05-02 11:21:57 -0700503 main.log.debug( self.name + ": Raw output from sending ''" )
504 main.log.debug( self.name + ": " + repr( response ) )
505 except pexpect.TIMEOUT:
506 main.log.error( self.name + ": ONOS timeout" )
507 main.log.debug( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700508 self.handle.send( "\x03" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800509 self.handle.expect( self.karafPrompt )
Jon Hall0e240372018-05-02 11:21:57 -0700510 return None
511 except pexpect.EOF:
512 main.log.error( self.name + ": EOF exception found" )
513 main.log.error( self.name + ": " + self.handle.before )
514 if noExit:
515 return None
516 else:
517 main.cleanAndExit()
518 except Exception:
519 main.log.exception( self.name + ": Uncaught exception!" )
520 if noExit:
521 return None
522 else:
523 main.cleanAndExit()
524
Jon Hall6c9e2da2018-11-06 12:01:23 -0800525 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True ):
Jon Hall0e240372018-05-02 11:21:57 -0700526 """
527 A wrapper around pexpect's sendline/expect. Will return all the output from a given command
528
529 Required Arguments:
530 cmdStr - String to send to the pexpect session
531
532 Optional Arguments:
533 showResponse - Defaults to False. If True will log the response.
534 debug - Defaults to False. If True, will enable debug logging.
535 timeout - Defaults to 10. Amount of time in seconds for a command to return
536 before a timeout.
537 noExit - Defaults to False. If True, will not exit TestON in the event of a
538 closed channel, but instead return None
Jon Hall6c9e2da2018-11-06 12:01:23 -0800539 relaxedRegex - Defaults to True. If there is a pipe in the command send, will only try to match the last part of the piped command.
Jon Hall0e240372018-05-02 11:21:57 -0700540
541 Warning: There are no sanity checking to commands sent using this method.
542
543 """
544 try:
545 # Try to reconnect if disconnected from cli
546 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
547 if debug:
548 # NOTE: This adds an average of .4 seconds per call
Jon Hall14a03b52016-05-11 12:07:30 -0700549 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700550 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800551 self.handle.sendline( cmdStr )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800552 self.handle.expect( self.karafPrompt, timeout )
Jon Hall63604932015-02-26 17:09:50 -0800553 response = self.handle.before
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000554 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800555 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700556 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700557 main.log.debug( self.name + ": Raw output" )
558 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700559
Jon Hall6c9e2da2018-11-06 12:01:23 -0800560 # Remove control codes from karaf 4.2.1
561 karafEscape = re.compile( r"('(0|1)~\'|\r\r\r\n\x1b\[A\x1b\[79Cx|\x1b(>|=)|\x1b\[90m~)" )
562 response = karafEscape.sub( '', response )
563 if debug:
564 main.log.debug( self.name + ": karafEscape output" )
565 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700566 # Remove ANSI color control strings from output
Jon Hall6c9e2da2018-11-06 12:01:23 -0800567 ansiEscape = re.compile( r'((\x9b|\x1b\[)[0-?]*[ -/]*[@-~])' )
Jon Hall63604932015-02-26 17:09:50 -0800568 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700569 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700570 main.log.debug( self.name + ": ansiEscape output" )
571 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700572
Jon Hall6c9e2da2018-11-06 12:01:23 -0800573 # Remove ANSI color control strings from output
574 backspaceEscape = re.compile( r'((..\x08\x08)|(.|\s)\x08)' )
575 response = backspaceEscape.sub( '', response )
576 if debug:
577 main.log.debug( self.name + ": backspaceEscape output" )
578 main.log.debug( self.name + ": " + repr( response ) )
579
kelvin-onlabfb521662015-02-27 09:52:40 -0800580 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000581 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700582 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700583 main.log.debug( self.name + ": Removed extra returns " +
584 "from output" )
585 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700586
587 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800588 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700589 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700590 main.log.debug( self.name + ": parsed and stripped output" )
591 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700592
Jon Hall63604932015-02-26 17:09:50 -0800593 # parse for just the output, remove the cmd from response
Jon Hall6c9e2da2018-11-06 12:01:23 -0800594 if relaxedRegex:
595 # This was added because karaf 4.2 is stripping some characters from the command echo
596 endStr = cmdStr.split( '|' )[-1]
597 main.log.warn( endStr )
598 output = response.split( endStr.strip(), 1 )
599 else:
600 output = response.split( cmdStr.strip(), 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700601 if output:
602 if debug:
603 main.log.debug( self.name + ": split output" )
604 for r in output:
605 main.log.debug( self.name + ": " + repr( r ) )
606 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800607 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800608 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700609 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800610 return output
GlennRCed771242016-01-13 17:02:47 -0800611 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700612 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800613 if debug:
614 main.log.debug( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700615 self.handle.send( "\x03" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800616 self.handle.expect( self.karafPrompt )
GlennRCed771242016-01-13 17:02:47 -0800617 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700618 except IndexError:
619 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700620 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700621 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800622 except TypeError:
623 main.log.exception( self.name + ": Object not as expected" )
624 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400625 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800626 main.log.error( self.name + ": EOF exception found" )
627 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700628 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700629 return None
630 else:
Devin Lim44075962017-08-11 10:56:37 -0700631 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800632 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800633 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700634 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700635 return None
636 else:
Devin Lim44075962017-08-11 10:56:37 -0700637 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400638
kelvin8ec71442015-01-15 16:57:00 -0800639 # IMPORTANT NOTE:
640 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800641 # the cli command changing 'a:b' with 'aB'.
642 # Ex ) onos:topology > onosTopology
643 # onos:links > onosLinks
644 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800645
kelvin-onlabd3b64892015-01-20 13:26:24 -0800646 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800647 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400648 Adds a new cluster node by ID and address information.
649 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800650 * nodeId
651 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400652 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800653 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800654 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400655 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800656 cmdStr = "add-node " + str( nodeId ) + " " +\
657 str( ONOSIp ) + " " + str( tcpPort )
658 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700659 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800660 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800661 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700662 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800663 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800664 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400665 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800666 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400667 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800668 except AssertionError:
669 main.log.exception( "" )
670 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800671 except TypeError:
672 main.log.exception( self.name + ": Object not as expected" )
673 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400674 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800675 main.log.error( self.name + ": EOF exception found" )
676 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700677 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800678 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800679 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700680 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400681
kelvin-onlabd3b64892015-01-20 13:26:24 -0800682 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800683 """
andrewonlab86dc3082014-10-13 18:18:38 -0400684 Removes a cluster by ID
685 Issues command: 'remove-node [<node-id>]'
686 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800687 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800688 """
andrewonlab86dc3082014-10-13 18:18:38 -0400689 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400690
kelvin-onlabd3b64892015-01-20 13:26:24 -0800691 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700692 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700693 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800694 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700695 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700696 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700697 main.log.error( handle )
698 return main.FALSE
699 else:
700 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800701 except AssertionError:
702 main.log.exception( "" )
703 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800704 except TypeError:
705 main.log.exception( self.name + ": Object not as expected" )
706 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400707 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800708 main.log.error( self.name + ": EOF exception found" )
709 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700710 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800711 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800712 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700713 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400714
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700715 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800716 """
andrewonlab7c211572014-10-15 16:45:20 -0400717 List the nodes currently visible
718 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700719 Optional argument:
720 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800721 """
andrewonlab7c211572014-10-15 16:45:20 -0400722 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700723 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700724 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700725 cmdStr += " -j"
726 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700727 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800728 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700729 return output
Jon Hallc6793552016-01-19 14:18:37 -0800730 except AssertionError:
731 main.log.exception( "" )
732 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800733 except TypeError:
734 main.log.exception( self.name + ": Object not as expected" )
735 return None
andrewonlab7c211572014-10-15 16:45:20 -0400736 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800737 main.log.error( self.name + ": EOF exception found" )
738 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700739 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800740 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800741 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700742 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400743
kelvin8ec71442015-01-15 16:57:00 -0800744 def topology( self ):
745 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700746 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700747 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700748 Return:
749 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800750 """
andrewonlab95ce8322014-10-13 14:12:04 -0400751 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700752 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800753 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800754 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800755 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700756 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400757 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800758 except AssertionError:
759 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800760 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800761 except TypeError:
762 main.log.exception( self.name + ": Object not as expected" )
763 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400764 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800765 main.log.error( self.name + ": EOF exception found" )
766 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700767 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800768 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800769 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700770 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800771
jenkins7ead5a82015-03-13 10:28:21 -0700772 def deviceRemove( self, deviceId ):
773 """
774 Removes particular device from storage
775
776 TODO: refactor this function
777 """
778 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700779 cmdStr = "device-remove " + str( deviceId )
780 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800781 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800782 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700783 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700784 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700785 main.log.error( handle )
786 return main.FALSE
787 else:
788 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800789 except AssertionError:
790 main.log.exception( "" )
791 return None
jenkins7ead5a82015-03-13 10:28:21 -0700792 except TypeError:
793 main.log.exception( self.name + ": Object not as expected" )
794 return None
795 except pexpect.EOF:
796 main.log.error( self.name + ": EOF exception found" )
797 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700798 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700799 except Exception:
800 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700801 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700802
You Wang3b9689a2018-08-30 12:24:00 -0700803 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800804 """
Jon Hall7b02d952014-10-17 20:14:54 -0400805 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400806 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800807 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800808 """
andrewonlab86dc3082014-10-13 18:18:38 -0400809 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700810 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800811 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700812 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700813 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800814 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800815 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700816 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800817 except AssertionError:
818 main.log.exception( "" )
819 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800820 except TypeError:
821 main.log.exception( self.name + ": Object not as expected" )
822 return None
andrewonlab7c211572014-10-15 16:45:20 -0400823 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800824 main.log.error( self.name + ": EOF exception found" )
825 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700826 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800827 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800828 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700829 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400830
kelvin-onlabd3b64892015-01-20 13:26:24 -0800831 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800832 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800833 This balances the devices across all controllers
834 by issuing command: 'onos> onos:balance-masters'
835 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800836 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800837 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800838 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700839 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800840 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800841 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700842 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700843 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700844 main.log.error( handle )
845 return main.FALSE
846 else:
847 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800848 except AssertionError:
849 main.log.exception( "" )
850 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800851 except TypeError:
852 main.log.exception( self.name + ": Object not as expected" )
853 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800854 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800855 main.log.error( self.name + ": EOF exception found" )
856 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700857 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800858 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800859 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700860 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800861
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000862 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700863 """
864 Returns the output of the masters command.
865 Optional argument:
866 * jsonFormat - boolean indicating if you want output in json
867 """
868 try:
869 cmdStr = "onos:masters"
870 if jsonFormat:
871 cmdStr += " -j"
872 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700873 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800874 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700875 return output
Jon Hallc6793552016-01-19 14:18:37 -0800876 except AssertionError:
877 main.log.exception( "" )
878 return None
acsmars24950022015-07-30 18:00:43 -0700879 except TypeError:
880 main.log.exception( self.name + ": Object not as expected" )
881 return None
882 except pexpect.EOF:
883 main.log.error( self.name + ": EOF exception found" )
884 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700885 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700886 except Exception:
887 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700888 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700889
Jon Hallc6793552016-01-19 14:18:37 -0800890 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700891 """
892 Uses the master command to check that the devices' leadership
893 is evenly divided
894
895 Dependencies: checkMasters() and summary()
896
Jon Hall6509dbf2016-06-21 17:01:17 -0700897 Returns main.TRUE if the devices are balanced
898 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700899 Exits on Exception
900 Returns None on TypeError
901 """
902 try:
Jon Hallc6793552016-01-19 14:18:37 -0800903 summaryOutput = self.summary()
904 totalDevices = json.loads( summaryOutput )[ "devices" ]
905 except ( TypeError, ValueError ):
906 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
907 return None
908 try:
acsmars24950022015-07-30 18:00:43 -0700909 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800910 mastersOutput = self.checkMasters()
911 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700912 first = masters[ 0 ][ "size" ]
913 for master in masters:
914 totalOwnedDevices += master[ "size" ]
915 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
916 main.log.error( "Mastership not balanced" )
917 main.log.info( "\n" + self.checkMasters( False ) )
918 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700919 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700920 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700921 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800922 except ( TypeError, ValueError ):
923 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700924 return None
925 except pexpect.EOF:
926 main.log.error( self.name + ": EOF exception found" )
927 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700928 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700929 except Exception:
930 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700931 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700932
YPZhangfebf7302016-05-24 16:45:56 -0700933 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800934 """
Jon Halle8217482014-10-17 13:49:14 -0400935 Lists all core links
936 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800937 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800938 """
Jon Halle8217482014-10-17 13:49:14 -0400939 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700940 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800941 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700942 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700943 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800944 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800945 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700946 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800947 except AssertionError:
948 main.log.exception( "" )
949 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800950 except TypeError:
951 main.log.exception( self.name + ": Object not as expected" )
952 return None
Jon Halle8217482014-10-17 13:49:14 -0400953 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800954 main.log.error( self.name + ": EOF exception found" )
955 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700956 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800957 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800958 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700959 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400960
You Wang3b9689a2018-08-30 12:24:00 -0700961 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800962 """
Jon Halle8217482014-10-17 13:49:14 -0400963 Lists all ports
964 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800966 """
Jon Halle8217482014-10-17 13:49:14 -0400967 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700968 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800969 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700970 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700971 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800972 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800973 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700974 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800975 except AssertionError:
976 main.log.exception( "" )
977 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800978 except TypeError:
979 main.log.exception( self.name + ": Object not as expected" )
980 return None
Jon Halle8217482014-10-17 13:49:14 -0400981 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800982 main.log.error( self.name + ": EOF exception found" )
983 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700984 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800985 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800986 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700987 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400988
kelvin-onlabd3b64892015-01-20 13:26:24 -0800989 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800990 """
Jon Hall983a1702014-10-28 18:44:22 -0400991 Lists all devices and the controllers with roles assigned to them
992 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800993 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800994 """
andrewonlab7c211572014-10-15 16:45:20 -0400995 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700996 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800997 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700998 cmdStr += " -j"
999 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001000 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001001 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001002 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001003 except AssertionError:
1004 main.log.exception( "" )
1005 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001006 except TypeError:
1007 main.log.exception( self.name + ": Object not as expected" )
1008 return None
Jon Hall983a1702014-10-28 18:44:22 -04001009 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001010 main.log.error( self.name + ": EOF exception found" )
1011 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001012 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001013 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001014 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001015 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -04001016
kelvin-onlabd3b64892015-01-20 13:26:24 -08001017 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001018 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001019 Given the a string containing the json representation of the "roles"
1020 cli command and a partial or whole device id, returns a json object
1021 containing the roles output for the first device whose id contains
1022 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001023
1024 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001025 A dict of the role assignments for the given device or
1026 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001027 """
Jon Hall983a1702014-10-28 18:44:22 -04001028 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001029 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001030 return None
1031 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001032 rawRoles = self.roles()
1033 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001034 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001035 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001036 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001037 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001038 return device
1039 return None
Jon Hallc6793552016-01-19 14:18:37 -08001040 except ( TypeError, ValueError ):
1041 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001042 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001043 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001044 main.log.error( self.name + ": EOF exception found" )
1045 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001046 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001047 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001048 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001049 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001050
kelvin-onlabd3b64892015-01-20 13:26:24 -08001051 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001052 """
Jon Hall94fd0472014-12-08 11:52:42 -08001053 Iterates through each device and checks if there is a master assigned
1054 Returns: main.TRUE if each device has a master
1055 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001056 """
Jon Hall94fd0472014-12-08 11:52:42 -08001057 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001058 rawRoles = self.roles()
1059 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001060 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001061 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001062 # print device
1063 if device[ 'master' ] == "none":
1064 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001065 return main.FALSE
1066 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001067 except ( TypeError, ValueError ):
1068 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001069 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001070 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001071 main.log.error( self.name + ": EOF exception found" )
1072 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001073 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001074 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001075 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001076 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001077
kelvin-onlabd3b64892015-01-20 13:26:24 -08001078 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001079 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001080 Returns string of paths, and the cost.
1081 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001082 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001083 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001084 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1085 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001086 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001087 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001088 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001089 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001090 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001091 else:
kelvin8ec71442015-01-15 16:57:00 -08001092 path = handle.split( ";" )[ 0 ]
1093 cost = handle.split( ";" )[ 1 ]
1094 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001095 except AssertionError:
1096 main.log.exception( "" )
1097 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001098 except TypeError:
1099 main.log.exception( self.name + ": Object not as expected" )
1100 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001101 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001102 main.log.error( self.name + ": EOF exception found" )
1103 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001104 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001105 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001106 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001107 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001108
kelvin-onlabd3b64892015-01-20 13:26:24 -08001109 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001110 """
Jon Hallffb386d2014-11-21 13:43:38 -08001111 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001112 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001113 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001114 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001115 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001116 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001118 cmdStr += " -j"
1119 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001120 if handle:
1121 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001122 # TODO: Maybe make this less hardcoded
1123 # ConsistentMap Exceptions
1124 assert "org.onosproject.store.service" not in handle
1125 # Node not leader
1126 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001127 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001128 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001129 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001130 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001131 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001132 except TypeError:
1133 main.log.exception( self.name + ": Object not as expected" )
1134 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001135 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001136 main.log.error( self.name + ": EOF exception found" )
1137 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001138 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001139 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001140 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001141 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001142
kelvin-onlabd3b64892015-01-20 13:26:24 -08001143 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001144 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001145 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001146
Jon Hallefbd9792015-03-05 16:11:36 -08001147 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001148 partial mac address
1149
Jon Hall42db6dc2014-10-24 19:03:48 -04001150 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001151 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001152 try:
kelvin8ec71442015-01-15 16:57:00 -08001153 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001154 return None
1155 else:
1156 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001157 rawHosts = self.hosts()
1158 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001159 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001160 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001161 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001162 if not host:
1163 pass
1164 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001165 return host
1166 return None
Jon Hallc6793552016-01-19 14:18:37 -08001167 except ( TypeError, ValueError ):
1168 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001169 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001170 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001171 main.log.error( self.name + ": EOF exception found" )
1172 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001173 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001174 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001175 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001176 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001177
kelvin-onlabd3b64892015-01-20 13:26:24 -08001178 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001179 """
1180 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001181 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001182
andrewonlab3f0a4af2014-10-17 12:25:14 -04001183 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001184 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001185 IMPORTANT:
1186 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001187 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001188 Furthermore, it assumes that value of VLAN is '-1'
1189 Description:
kelvin8ec71442015-01-15 16:57:00 -08001190 Converts mininet hosts ( h1, h2, h3... ) into
1191 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1192 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001193 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001194 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001195
kelvin-onlabd3b64892015-01-20 13:26:24 -08001196 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001197 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 hostHex = hex( int( host ) ).zfill( 12 )
1199 hostHex = str( hostHex ).replace( 'x', '0' )
1200 i = iter( str( hostHex ) )
1201 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1202 hostHex = hostHex + "/-1"
1203 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001204
kelvin-onlabd3b64892015-01-20 13:26:24 -08001205 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001206
Jon Halld4d4b372015-01-28 16:02:41 -08001207 except TypeError:
1208 main.log.exception( self.name + ": Object not as expected" )
1209 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001210 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001211 main.log.error( self.name + ": EOF exception found" )
1212 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001213 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001214 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001215 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001216 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001217
You Wangbc898b82018-05-03 16:22:34 -07001218 def verifyHostLocation( self, hostIp, location ):
1219 """
1220 Description:
1221 Verify the host given is discovered in all locations expected
1222 Required:
1223 hostIp: IP address of the host
1224 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1225 Could be a string or list
1226 Returns:
1227 main.TRUE if host is discovered on all locations provided
1228 main.FALSE otherwise
1229 """
1230 import json
1231 locations = [ location ] if isinstance( location, str ) else location
1232 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1233 try:
1234 hosts = self.hosts()
1235 hosts = json.loads( hosts )
1236 targetHost = None
1237 for host in hosts:
1238 if hostIp in host[ "ipAddresses" ]:
1239 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001240 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001241 result = main.TRUE
1242 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1243 for loc in locations:
1244 discovered = False
1245 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001246 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1247 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001248 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001249 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001250 break
1251 if discovered:
1252 locationsDiscovered.remove( locDiscovered )
1253 else:
1254 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1255 result = main.FALSE
1256 if locationsDiscovered:
1257 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1258 result = main.FALSE
1259 return result
1260 except KeyError:
1261 main.log.exception( self.name + ": host data not as expected: " + hosts )
1262 return None
1263 except pexpect.EOF:
1264 main.log.error( self.name + ": EOF exception found" )
1265 main.log.error( self.name + ": " + self.handle.before )
1266 main.cleanAndExit()
1267 except Exception:
1268 main.log.exception( self.name + ": Uncaught exception" )
1269 return None
1270
You Wang53dba1e2018-02-02 17:45:44 -08001271 def verifyHostIp( self, hostList=[], prefix="" ):
1272 """
1273 Description:
1274 Verify that all hosts have IP address assigned to them
1275 Optional:
1276 hostList: If specified, verifications only happen to the hosts
1277 in hostList
1278 prefix: at least one of the ip address assigned to the host
1279 needs to have the specified prefix
1280 Returns:
1281 main.TRUE if all hosts have specific IP address assigned;
1282 main.FALSE otherwise
1283 """
1284 import json
1285 try:
1286 hosts = self.hosts()
1287 hosts = json.loads( hosts )
1288 if not hostList:
1289 hostList = [ host[ "id" ] for host in hosts ]
1290 for host in hosts:
1291 hostId = host[ "id" ]
1292 if hostId not in hostList:
1293 continue
1294 ipList = host[ "ipAddresses" ]
1295 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1296 if not ipList:
1297 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1298 else:
1299 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1300 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1301 else:
1302 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1303 hostList.remove( hostId )
1304 if hostList:
1305 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1306 return main.FALSE
1307 else:
1308 return main.TRUE
1309 except KeyError:
1310 main.log.exception( self.name + ": host data not as expected: " + hosts )
1311 return None
1312 except pexpect.EOF:
1313 main.log.error( self.name + ": EOF exception found" )
1314 main.log.error( self.name + ": " + self.handle.before )
1315 main.cleanAndExit()
1316 except Exception:
1317 main.log.exception( self.name + ": Uncaught exception" )
1318 return None
1319
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001320 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001321 """
andrewonlabe6745342014-10-17 14:29:13 -04001322 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001323 * hostIdOne: ONOS host id for host1
1324 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001325 Optional:
1326 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001327 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001328 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001329 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001330 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001331 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001332 Returns:
1333 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001334 """
andrewonlabe6745342014-10-17 14:29:13 -04001335 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001336 cmdStr = "add-host-intent "
1337 if vlanId:
1338 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001339 if setVlan:
1340 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001341 if encap:
1342 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001343 if bandwidth:
1344 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001345 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001346 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001347 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001348 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001349 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001350 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001351 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001352 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001353 else:
1354 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001355 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001356 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001357 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001358 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001359 else:
1360 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001361 main.log.debug( "Response from ONOS was: " +
1362 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001363 return None
Jon Hallc6793552016-01-19 14:18:37 -08001364 except AssertionError:
1365 main.log.exception( "" )
1366 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001367 except TypeError:
1368 main.log.exception( self.name + ": Object not as expected" )
1369 return None
andrewonlabe6745342014-10-17 14:29:13 -04001370 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001371 main.log.error( self.name + ": EOF exception found" )
1372 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001373 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001374 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001375 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001376 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001377
kelvin-onlabd3b64892015-01-20 13:26:24 -08001378 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001379 """
andrewonlab7b31d232014-10-24 13:31:47 -04001380 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001381 * ingressDevice: device id of ingress device
1382 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001383 Optional:
1384 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001385 Description:
1386 Adds an optical intent by specifying an ingress and egress device
1387 Returns:
1388 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001389 """
andrewonlab7b31d232014-10-24 13:31:47 -04001390 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001391 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1392 " " + str( egressDevice )
1393 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001394 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001395 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001396 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001397 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001398 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001399 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001400 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001401 main.log.info( "Optical intent installed between " +
1402 str( ingressDevice ) + " and " +
1403 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001404 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001405 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001406 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001407 else:
1408 main.log.error( "Error, intent ID not found" )
1409 return None
Jon Hallc6793552016-01-19 14:18:37 -08001410 except AssertionError:
1411 main.log.exception( "" )
1412 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001413 except TypeError:
1414 main.log.exception( self.name + ": Object not as expected" )
1415 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001416 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001417 main.log.error( self.name + ": EOF exception found" )
1418 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001419 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001420 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001421 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001422 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001423
kelvin-onlabd3b64892015-01-20 13:26:24 -08001424 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001425 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001426 ingressDevice,
1427 egressDevice,
1428 portIngress="",
1429 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001430 ethType="",
1431 ethSrc="",
1432 ethDst="",
1433 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001434 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001435 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001436 ipProto="",
1437 ipSrc="",
1438 ipDst="",
1439 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001440 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001441 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001442 setVlan="",
1443 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001444 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001445 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001446 * ingressDevice: device id of ingress device
1447 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001448 Optional:
1449 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001450 * ethSrc: specify ethSrc ( i.e. src mac addr )
1451 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001452 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001453 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001454 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001455 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001456 * ipSrc: specify ip source address
1457 * ipDst: specify ip destination address
1458 * tcpSrc: specify tcp source port
1459 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001460 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001461 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001462 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001463 Description:
kelvin8ec71442015-01-15 16:57:00 -08001464 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001465 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001466 Returns:
1467 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001468
Jon Halle3f39ff2015-01-13 11:50:53 -08001469 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001470 options developers provide for point-to-point
1471 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001472 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001473 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001474 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001475
Jeremy Songsterff553672016-05-12 17:06:23 -07001476 if ethType:
1477 cmd += " --ethType " + str( ethType )
1478 if ethSrc:
1479 cmd += " --ethSrc " + str( ethSrc )
1480 if ethDst:
1481 cmd += " --ethDst " + str( ethDst )
1482 if bandwidth:
1483 cmd += " --bandwidth " + str( bandwidth )
1484 if lambdaAlloc:
1485 cmd += " --lambda "
1486 if ipProto:
1487 cmd += " --ipProto " + str( ipProto )
1488 if ipSrc:
1489 cmd += " --ipSrc " + str( ipSrc )
1490 if ipDst:
1491 cmd += " --ipDst " + str( ipDst )
1492 if tcpSrc:
1493 cmd += " --tcpSrc " + str( tcpSrc )
1494 if tcpDst:
1495 cmd += " --tcpDst " + str( tcpDst )
1496 if vlanId:
1497 cmd += " -v " + str( vlanId )
1498 if setVlan:
1499 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001500 if encap:
1501 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001502 if protected:
1503 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001504
kelvin8ec71442015-01-15 16:57:00 -08001505 # Check whether the user appended the port
1506 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001507 if "/" in ingressDevice:
1508 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001509 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001510 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001511 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001512 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001513 # Would it make sense to throw an exception and exit
1514 # the test?
1515 return None
andrewonlab36af3822014-11-18 17:48:18 -05001516
kelvin8ec71442015-01-15 16:57:00 -08001517 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001518 str( ingressDevice ) + "/" +\
1519 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001520
kelvin-onlabd3b64892015-01-20 13:26:24 -08001521 if "/" in egressDevice:
1522 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001523 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001524 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001525 main.log.error( "You must specify the egress port" )
1526 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001527
kelvin8ec71442015-01-15 16:57:00 -08001528 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001529 str( egressDevice ) + "/" +\
1530 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001531
kelvin-onlab898a6c62015-01-16 14:13:53 -08001532 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001533 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001534 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001535 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001536 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001537 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001538 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001539 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001540 # TODO: print out all the options in this message?
1541 main.log.info( "Point-to-point intent installed between " +
1542 str( ingressDevice ) + " and " +
1543 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001544 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001545 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001546 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001547 else:
1548 main.log.error( "Error, intent ID not found" )
1549 return None
Jon Hallc6793552016-01-19 14:18:37 -08001550 except AssertionError:
1551 main.log.exception( "" )
1552 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001553 except TypeError:
1554 main.log.exception( self.name + ": Object not as expected" )
1555 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001556 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001557 main.log.error( self.name + ": EOF exception found" )
1558 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001559 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001560 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001561 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001562 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001563
kelvin-onlabd3b64892015-01-20 13:26:24 -08001564 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001565 self,
shahshreyac2f97072015-03-19 17:04:29 -07001566 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001567 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001568 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001569 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001570 ethType="",
1571 ethSrc="",
1572 ethDst="",
1573 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001575 ipProto="",
1576 ipSrc="",
1577 ipDst="",
1578 tcpSrc="",
1579 tcpDst="",
1580 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001581 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001582 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001583 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001584 partial=False,
1585 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001586 """
shahshreyad0c80432014-12-04 16:56:05 -08001587 Note:
shahshreya70622b12015-03-19 17:19:00 -07001588 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001589 is same. That is, all ingress devices include port numbers
1590 with a "/" or all ingress devices could specify device
1591 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001592 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001593 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001594 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001595 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001596 Optional:
1597 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001598 * ethSrc: specify ethSrc ( i.e. src mac addr )
1599 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001600 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001601 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001602 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001603 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001604 * ipSrc: specify ip source address
1605 * ipDst: specify ip destination address
1606 * tcpSrc: specify tcp source port
1607 * tcpDst: specify tcp destination port
1608 * setEthSrc: action to Rewrite Source MAC Address
1609 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001610 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001611 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001612 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001613 Description:
kelvin8ec71442015-01-15 16:57:00 -08001614 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001615 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001616 Returns:
1617 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001618
Jon Halle3f39ff2015-01-13 11:50:53 -08001619 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001620 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001621 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001622 """
shahshreyad0c80432014-12-04 16:56:05 -08001623 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001624 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001625
Jeremy Songsterff553672016-05-12 17:06:23 -07001626 if ethType:
1627 cmd += " --ethType " + str( ethType )
1628 if ethSrc:
1629 cmd += " --ethSrc " + str( ethSrc )
1630 if ethDst:
1631 cmd += " --ethDst " + str( ethDst )
1632 if bandwidth:
1633 cmd += " --bandwidth " + str( bandwidth )
1634 if lambdaAlloc:
1635 cmd += " --lambda "
1636 if ipProto:
1637 cmd += " --ipProto " + str( ipProto )
1638 if ipSrc:
1639 cmd += " --ipSrc " + str( ipSrc )
1640 if ipDst:
1641 cmd += " --ipDst " + str( ipDst )
1642 if tcpSrc:
1643 cmd += " --tcpSrc " + str( tcpSrc )
1644 if tcpDst:
1645 cmd += " --tcpDst " + str( tcpDst )
1646 if setEthSrc:
1647 cmd += " --setEthSrc " + str( setEthSrc )
1648 if setEthDst:
1649 cmd += " --setEthDst " + str( setEthDst )
1650 if vlanId:
1651 cmd += " -v " + str( vlanId )
1652 if setVlan:
1653 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001654 if partial:
1655 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001656 if encap:
1657 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001658
kelvin8ec71442015-01-15 16:57:00 -08001659 # Check whether the user appended the port
1660 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001661
1662 if portIngressList is None:
1663 for ingressDevice in ingressDeviceList:
1664 if "/" in ingressDevice:
1665 cmd += " " + str( ingressDevice )
1666 else:
1667 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001668 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001669 # TODO: perhaps more meaningful return
1670 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001671 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001672 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001673 for ingressDevice, portIngress in zip( ingressDeviceList,
1674 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001675 cmd += " " + \
1676 str( ingressDevice ) + "/" +\
1677 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001678 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001679 main.log.error( "Device list and port list does not " +
1680 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001681 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001682 if "/" in egressDevice:
1683 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001684 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001685 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001686 main.log.error( "You must specify " +
1687 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001688 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001689
kelvin8ec71442015-01-15 16:57:00 -08001690 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001691 str( egressDevice ) + "/" +\
1692 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001693 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001694 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001695 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001696 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001697 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001698 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001699 "intent" )
1700 return None
shahshreyad0c80432014-12-04 16:56:05 -08001701 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001702 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001703 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001704 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001705 else:
1706 main.log.error( "Error, intent ID not found" )
1707 return None
Jon Hallc6793552016-01-19 14:18:37 -08001708 except AssertionError:
1709 main.log.exception( "" )
1710 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001711 except TypeError:
1712 main.log.exception( self.name + ": Object not as expected" )
1713 return None
1714 except pexpect.EOF:
1715 main.log.error( self.name + ": EOF exception found" )
1716 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001717 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001718 except Exception:
1719 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001720 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001721
1722 def addSinglepointToMultipointIntent(
1723 self,
1724 ingressDevice,
1725 egressDeviceList,
1726 portIngress="",
1727 portEgressList=None,
1728 ethType="",
1729 ethSrc="",
1730 ethDst="",
1731 bandwidth="",
1732 lambdaAlloc=False,
1733 ipProto="",
1734 ipSrc="",
1735 ipDst="",
1736 tcpSrc="",
1737 tcpDst="",
1738 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001739 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001740 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001741 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001742 partial=False,
1743 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001744 """
1745 Note:
1746 This function assumes the format of all egress devices
1747 is same. That is, all egress devices include port numbers
1748 with a "/" or all egress devices could specify device
1749 ids and port numbers seperately.
1750 Required:
1751 * EgressDeviceList: List of device ids of egress device
1752 ( Atleast 2 eress devices required in the list )
1753 * ingressDevice: device id of ingress device
1754 Optional:
1755 * ethType: specify ethType
1756 * ethSrc: specify ethSrc ( i.e. src mac addr )
1757 * ethDst: specify ethDst ( i.e. dst mac addr )
1758 * bandwidth: specify bandwidth capacity of link
1759 * lambdaAlloc: if True, intent will allocate lambda
1760 for the specified intent
1761 * ipProto: specify ip protocol
1762 * ipSrc: specify ip source address
1763 * ipDst: specify ip destination address
1764 * tcpSrc: specify tcp source port
1765 * tcpDst: specify tcp destination port
1766 * setEthSrc: action to Rewrite Source MAC Address
1767 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001768 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001769 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001770 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001771 Description:
1772 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1773 specifying device id's and optional fields
1774 Returns:
1775 A string of the intent id or None on error
1776
1777 NOTE: This function may change depending on the
1778 options developers provide for singlepoint-to-multipoint
1779 intent via cli
1780 """
1781 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001782 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001783
Jeremy Songsterff553672016-05-12 17:06:23 -07001784 if ethType:
1785 cmd += " --ethType " + str( ethType )
1786 if ethSrc:
1787 cmd += " --ethSrc " + str( ethSrc )
1788 if ethDst:
1789 cmd += " --ethDst " + str( ethDst )
1790 if bandwidth:
1791 cmd += " --bandwidth " + str( bandwidth )
1792 if lambdaAlloc:
1793 cmd += " --lambda "
1794 if ipProto:
1795 cmd += " --ipProto " + str( ipProto )
1796 if ipSrc:
1797 cmd += " --ipSrc " + str( ipSrc )
1798 if ipDst:
1799 cmd += " --ipDst " + str( ipDst )
1800 if tcpSrc:
1801 cmd += " --tcpSrc " + str( tcpSrc )
1802 if tcpDst:
1803 cmd += " --tcpDst " + str( tcpDst )
1804 if setEthSrc:
1805 cmd += " --setEthSrc " + str( setEthSrc )
1806 if setEthDst:
1807 cmd += " --setEthDst " + str( setEthDst )
1808 if vlanId:
1809 cmd += " -v " + str( vlanId )
1810 if setVlan:
1811 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001812 if partial:
1813 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001814 if encap:
1815 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001816
1817 # Check whether the user appended the port
1818 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001819
kelvin-onlabb9408212015-04-01 13:34:04 -07001820 if "/" in ingressDevice:
1821 cmd += " " + str( ingressDevice )
1822 else:
1823 if not portIngress:
1824 main.log.error( "You must specify " +
1825 "the Ingress port" )
1826 return main.FALSE
1827
1828 cmd += " " +\
1829 str( ingressDevice ) + "/" +\
1830 str( portIngress )
1831
1832 if portEgressList is None:
1833 for egressDevice in egressDeviceList:
1834 if "/" in egressDevice:
1835 cmd += " " + str( egressDevice )
1836 else:
1837 main.log.error( "You must specify " +
1838 "the egress port" )
1839 # TODO: perhaps more meaningful return
1840 return main.FALSE
1841 else:
1842 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001843 for egressDevice, portEgress in zip( egressDeviceList,
1844 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001845 cmd += " " + \
1846 str( egressDevice ) + "/" +\
1847 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001848 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001849 main.log.error( "Device list and port list does not " +
1850 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001851 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001852 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001853 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001854 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001855 # If error, return error message
1856 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001857 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001858 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001859 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001860 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001861 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001862 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001863 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001864 else:
1865 main.log.error( "Error, intent ID not found" )
1866 return None
Jon Hallc6793552016-01-19 14:18:37 -08001867 except AssertionError:
1868 main.log.exception( "" )
1869 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001870 except TypeError:
1871 main.log.exception( self.name + ": Object not as expected" )
1872 return None
shahshreyad0c80432014-12-04 16:56:05 -08001873 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001874 main.log.error( self.name + ": EOF exception found" )
1875 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001876 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001877 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001878 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001879 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001880
Hari Krishna9e232602015-04-13 17:29:08 -07001881 def addMplsIntent(
1882 self,
1883 ingressDevice,
1884 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001885 ingressPort="",
1886 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001887 ethType="",
1888 ethSrc="",
1889 ethDst="",
1890 bandwidth="",
1891 lambdaAlloc=False,
1892 ipProto="",
1893 ipSrc="",
1894 ipDst="",
1895 tcpSrc="",
1896 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001897 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001898 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001899 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001900 """
1901 Required:
1902 * ingressDevice: device id of ingress device
1903 * egressDevice: device id of egress device
1904 Optional:
1905 * ethType: specify ethType
1906 * ethSrc: specify ethSrc ( i.e. src mac addr )
1907 * ethDst: specify ethDst ( i.e. dst mac addr )
1908 * bandwidth: specify bandwidth capacity of link
1909 * lambdaAlloc: if True, intent will allocate lambda
1910 for the specified intent
1911 * ipProto: specify ip protocol
1912 * ipSrc: specify ip source address
1913 * ipDst: specify ip destination address
1914 * tcpSrc: specify tcp source port
1915 * tcpDst: specify tcp destination port
1916 * ingressLabel: Ingress MPLS label
1917 * egressLabel: Egress MPLS label
1918 Description:
1919 Adds MPLS intent by
1920 specifying device id's and optional fields
1921 Returns:
1922 A string of the intent id or None on error
1923
1924 NOTE: This function may change depending on the
1925 options developers provide for MPLS
1926 intent via cli
1927 """
1928 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001929 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001930
Jeremy Songsterff553672016-05-12 17:06:23 -07001931 if ethType:
1932 cmd += " --ethType " + str( ethType )
1933 if ethSrc:
1934 cmd += " --ethSrc " + str( ethSrc )
1935 if ethDst:
1936 cmd += " --ethDst " + str( ethDst )
1937 if bandwidth:
1938 cmd += " --bandwidth " + str( bandwidth )
1939 if lambdaAlloc:
1940 cmd += " --lambda "
1941 if ipProto:
1942 cmd += " --ipProto " + str( ipProto )
1943 if ipSrc:
1944 cmd += " --ipSrc " + str( ipSrc )
1945 if ipDst:
1946 cmd += " --ipDst " + str( ipDst )
1947 if tcpSrc:
1948 cmd += " --tcpSrc " + str( tcpSrc )
1949 if tcpDst:
1950 cmd += " --tcpDst " + str( tcpDst )
1951 if ingressLabel:
1952 cmd += " --ingressLabel " + str( ingressLabel )
1953 if egressLabel:
1954 cmd += " --egressLabel " + str( egressLabel )
1955 if priority:
1956 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001957
1958 # Check whether the user appended the port
1959 # or provided it as an input
1960 if "/" in ingressDevice:
1961 cmd += " " + str( ingressDevice )
1962 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001963 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001964 main.log.error( "You must specify the ingress port" )
1965 return None
1966
1967 cmd += " " + \
1968 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001969 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001970
1971 if "/" in egressDevice:
1972 cmd += " " + str( egressDevice )
1973 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001974 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001975 main.log.error( "You must specify the egress port" )
1976 return None
1977
1978 cmd += " " +\
1979 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001980 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001981
1982 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001983 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001984 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001985 # If error, return error message
1986 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001987 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07001988 return None
1989 else:
1990 # TODO: print out all the options in this message?
1991 main.log.info( "MPLS intent installed between " +
1992 str( ingressDevice ) + " and " +
1993 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001994 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07001995 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001996 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07001997 else:
1998 main.log.error( "Error, intent ID not found" )
1999 return None
Jon Hallc6793552016-01-19 14:18:37 -08002000 except AssertionError:
2001 main.log.exception( "" )
2002 return None
Hari Krishna9e232602015-04-13 17:29:08 -07002003 except TypeError:
2004 main.log.exception( self.name + ": Object not as expected" )
2005 return None
2006 except pexpect.EOF:
2007 main.log.error( self.name + ": EOF exception found" )
2008 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002009 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002010 except Exception:
2011 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002012 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002013
Jon Hallefbd9792015-03-05 16:11:36 -08002014 def removeIntent( self, intentId, app='org.onosproject.cli',
2015 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002016 """
shahshreya1c818fc2015-02-26 13:44:08 -08002017 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07002018 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08002019 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07002020 -p or --purge: Purge the intent from the store after removal
2021
Jon Halle3f39ff2015-01-13 11:50:53 -08002022 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002023 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002024 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002025 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002026 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002027 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002028 if purge:
2029 cmdStr += " -p"
2030 if sync:
2031 cmdStr += " -s"
2032
2033 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002034 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002035 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002036 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002037 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002038 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002039 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002040 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002041 # TODO: Should this be main.TRUE
2042 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002043 except AssertionError:
2044 main.log.exception( "" )
2045 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002046 except TypeError:
2047 main.log.exception( self.name + ": Object not as expected" )
2048 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002049 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002050 main.log.error( self.name + ": EOF exception found" )
2051 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002052 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002053 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002054 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002055 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002056
YPZhangfebf7302016-05-24 16:45:56 -07002057 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002058 """
2059 Description:
2060 Remove all the intents
2061 Optional args:-
2062 -s or --sync: Waits for the removal before returning
2063 -p or --purge: Purge the intent from the store after removal
2064 Returns:
2065 Returns main.TRUE if all intents are removed, otherwise returns
2066 main.FALSE; Returns None for exception
2067 """
2068 try:
2069 cmdStr = "remove-intent"
2070 if purge:
2071 cmdStr += " -p"
2072 if sync:
2073 cmdStr += " -s"
2074
2075 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002076 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002077 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002078 assert "Command not found:" not in handle, handle
2079 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002080 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002081 return main.FALSE
2082 else:
2083 return main.TRUE
2084 except AssertionError:
2085 main.log.exception( "" )
2086 return None
2087 except TypeError:
2088 main.log.exception( self.name + ": Object not as expected" )
2089 return None
2090 except pexpect.EOF:
2091 main.log.error( self.name + ": EOF exception found" )
2092 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002093 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002094 except Exception:
2095 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002096 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002097
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002098 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002099 """
2100 Purges all WITHDRAWN Intents
2101 """
2102 try:
2103 cmdStr = "purge-intents"
2104 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002105 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002106 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002107 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002108 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002109 return main.FALSE
2110 else:
2111 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002112 except AssertionError:
2113 main.log.exception( "" )
2114 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002115 except TypeError:
2116 main.log.exception( self.name + ": Object not as expected" )
2117 return None
2118 except pexpect.EOF:
2119 main.log.error( self.name + ": EOF exception found" )
2120 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002121 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002122 except Exception:
2123 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002124 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002125
Devin Lime6fe3c42017-10-18 16:28:40 -07002126 def wipeout( self ):
2127 """
2128 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2129 """
2130 try:
2131 cmdStr = "wipe-out please"
2132 handle = self.sendline( cmdStr, timeout=60 )
2133 assert handle is not None, "Error in sendline"
2134 assert "Command not found:" not in handle, handle
2135 return main.TRUE
2136 except AssertionError:
2137 main.log.exception( "" )
2138 return None
2139 except TypeError:
2140 main.log.exception( self.name + ": Object not as expected" )
2141 return None
2142 except pexpect.EOF:
2143 main.log.error( self.name + ": EOF exception found" )
2144 main.log.error( self.name + ": " + self.handle.before )
2145 main.cleanAndExit()
2146 except Exception:
2147 main.log.exception( self.name + ": Uncaught exception!" )
2148 main.cleanAndExit()
2149
kelvin-onlabd3b64892015-01-20 13:26:24 -08002150 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002151 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002152 NOTE: This method should be used after installing application:
2153 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002154 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002155 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002156 Description:
2157 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002158 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002159 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002160 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002161 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002162 cmdStr += " -j"
2163 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002164 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002165 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002166 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002167 except AssertionError:
2168 main.log.exception( "" )
2169 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002170 except TypeError:
2171 main.log.exception( self.name + ": Object not as expected" )
2172 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002173 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002174 main.log.error( self.name + ": EOF exception found" )
2175 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002176 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002177 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002178 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002179 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002180
pingping-lin54b03372015-08-13 14:43:10 -07002181 def ipv4RouteNumber( self ):
2182 """
2183 NOTE: This method should be used after installing application:
2184 onos-app-sdnip
2185 Description:
2186 Obtain the total IPv4 routes number in the system
2187 """
2188 try:
Pratik Parab57963572017-05-09 11:37:54 -07002189 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002190 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002191 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002192 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002193 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002194 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002195 except AssertionError:
2196 main.log.exception( "" )
2197 return None
2198 except ( TypeError, ValueError ):
2199 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002200 return None
2201 except pexpect.EOF:
2202 main.log.error( self.name + ": EOF exception found" )
2203 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002204 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002205 except Exception:
2206 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002207 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002208
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002209 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002210 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002211 """
2212 Description:
2213 Obtain Bandwidth Allocation Information from ONOS cli.
2214 """
2215 try:
2216 cmdStr = "allocations"
2217 if jsonFormat:
2218 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002219 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002220 assert handle is not None, "Error in sendline"
2221 assert "Command not found:" not in handle, handle
2222 return handle
2223 except AssertionError:
2224 main.log.exception( "" )
2225 return None
2226 except ( TypeError, ValueError ):
2227 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2228 return None
2229 except pexpect.EOF:
2230 main.log.error( self.name + ": EOF exception found" )
2231 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002232 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002233 except Exception:
2234 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002235 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002236
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002237 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002238 """
andrewonlabe6745342014-10-17 14:29:13 -04002239 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002240 Obtain intents from the ONOS cli.
2241 Optional:
2242 * jsonFormat: Enable output formatting in json, default to True
2243 * summary: Whether only output the intent summary, defaults to False
2244 * type: Only output a certain type of intent. This options is valid
2245 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002246 """
andrewonlabe6745342014-10-17 14:29:13 -04002247 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002248 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002249 if summary:
2250 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002251 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002252 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002253 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002254 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002255 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002256 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002257 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002258 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002259 else:
Jon Hallff566d52016-01-15 14:45:36 -08002260 intentType = ""
2261 # IF we want the summary of a specific intent type
2262 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002263 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002264 if intentType in jsonResult.keys():
2265 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002266 else:
Jon Hallff566d52016-01-15 14:45:36 -08002267 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002268 return handle
2269 else:
2270 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002271 except AssertionError:
2272 main.log.exception( "" )
2273 return None
2274 except ( TypeError, ValueError ):
2275 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002276 return None
2277 except pexpect.EOF:
2278 main.log.error( self.name + ": EOF exception found" )
2279 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002280 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002281 except Exception:
2282 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002283 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002284
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002285 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002286 """
You Wangfdcbfc42016-05-16 12:16:53 -07002287 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002288 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002289 list of intent IDs.
2290 Parameters:
2291 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002292 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002293 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002294 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002295 accepted.
2296 Returns a list of dictionaries if a list of intent IDs is accepted,
2297 and each dictionary maps 'id' to the Intent ID and 'state' to
2298 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002299 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002300
kelvin-onlab54400a92015-02-26 18:05:51 -08002301 try:
2302 state = "State is Undefined"
2303 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002304 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002305 else:
Jon Hallc6793552016-01-19 14:18:37 -08002306 rawJson = intentsJson
2307 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002308 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002309 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002310 if intentsId == intent[ 'id' ]:
2311 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002312 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002313 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002314 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002315 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002316 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002317 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002318 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002319 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002320 for intent in parsedIntentsJson:
2321 if intentsId[ i ] == intent[ 'id' ]:
2322 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002323 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002324 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002325 break
Jon Hallefbd9792015-03-05 16:11:36 -08002326 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002327 main.log.warn( "Could not find all intents in ONOS output" )
2328 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002329 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002330 else:
Jon Hall53158082017-05-18 11:17:00 -07002331 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002332 return None
Jon Hallc6793552016-01-19 14:18:37 -08002333 except ( TypeError, ValueError ):
2334 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002335 return None
2336 except pexpect.EOF:
2337 main.log.error( self.name + ": EOF exception found" )
2338 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002339 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002340 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002341 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002342 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002343
Jon Hallf539eb92017-05-22 17:18:42 -07002344 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002345 """
2346 Description:
2347 Check intents state
2348 Required:
2349 intentsId - List of intents ID to be checked
2350 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002351 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002352 state in the list.
2353 *NOTE: You can pass in a list of expected state,
2354 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002355 Return:
Jon Hall53158082017-05-18 11:17:00 -07002356 Returns main.TRUE only if all intent are the same as expected states,
2357 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002358 """
2359 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002360 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002361 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002362
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002363 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002364 intentsDict = []
2365 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002366 if isinstance( intentsId, types.StringType ) \
2367 and intent.get( 'id' ) == intentsId:
2368 intentsDict.append( intent )
2369 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002370 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002371 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002372
2373 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002374 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002375 "getting intents state" )
2376 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002377
2378 if isinstance( expectedState, types.StringType ):
2379 for intents in intentsDict:
2380 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002381 main.log.debug( self.name + " : Intent ID - " +
2382 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002383 " actual state = " +
2384 intents.get( 'state' )
2385 + " does not equal expected state = "
2386 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002387 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002388 elif isinstance( expectedState, types.ListType ):
2389 for intents in intentsDict:
2390 if not any( state == intents.get( 'state' ) for state in
2391 expectedState ):
2392 main.log.debug( self.name + " : Intent ID - " +
2393 intents.get( 'id' ) +
2394 " actual state = " +
2395 intents.get( 'state' ) +
2396 " does not equal expected states = "
2397 + str( expectedState ) )
2398 returnValue = main.FALSE
2399
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002400 if returnValue == main.TRUE:
2401 main.log.info( self.name + ": All " +
2402 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002403 " intents are in " + str( expectedState ) +
2404 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002405 return returnValue
2406 except TypeError:
2407 main.log.exception( self.name + ": Object not as expected" )
2408 return None
2409 except pexpect.EOF:
2410 main.log.error( self.name + ": EOF exception found" )
2411 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002412 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002413 except Exception:
2414 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002415 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002416
Jon Hallf539eb92017-05-22 17:18:42 -07002417 def compareBandwidthAllocations( self, expectedAllocations ):
2418 """
2419 Description:
2420 Compare the allocated bandwidth with the given allocations
2421 Required:
2422 expectedAllocations - The expected ONOS output of the allocations command
2423 Return:
2424 Returns main.TRUE only if all intent are the same as expected states,
2425 otherwise returns main.FALSE.
2426 """
2427 # FIXME: Convert these string comparisons to object comparisons
2428 try:
2429 returnValue = main.TRUE
2430 bandwidthFailed = False
2431 rawAlloc = self.allocations()
2432 expectedFormat = StringIO( expectedAllocations )
2433 ONOSOutput = StringIO( rawAlloc )
2434 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2435 str( expectedFormat ) ) )
2436
2437 for actual, expected in izip( ONOSOutput, expectedFormat ):
2438 actual = actual.rstrip()
2439 expected = expected.rstrip()
2440 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2441 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002442 marker1 = actual.find( 'allocated' )
2443 m1 = actual[ :marker1 ]
2444 marker2 = expected.find( 'allocated' )
2445 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002446 if m1 != m2:
2447 bandwidthFailed = True
2448 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2449 bandwidthFailed = True
2450 expectedFormat.close()
2451 ONOSOutput.close()
2452
2453 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002454 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002455 returnValue = main.FALSE
2456 return returnValue
2457 except TypeError:
2458 main.log.exception( self.name + ": Object not as expected" )
2459 return None
2460 except pexpect.EOF:
2461 main.log.error( self.name + ": EOF exception found" )
2462 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002463 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002464 except Exception:
2465 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002466 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002467
You Wang66518af2016-05-16 15:32:59 -07002468 def compareIntent( self, intentDict ):
2469 """
2470 Description:
2471 Compare the intent ids and states provided in the argument with all intents in ONOS
2472 Return:
2473 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2474 Arguments:
2475 intentDict: a dictionary which maps intent ids to intent states
2476 """
2477 try:
2478 intentsRaw = self.intents()
2479 intentsJson = json.loads( intentsRaw )
2480 intentDictONOS = {}
2481 for intent in intentsJson:
2482 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002483 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002484 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002485 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002486 str( len( intentDict ) ) + " expected and " +
2487 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002488 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002489 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002490 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002491 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2492 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002493 else:
2494 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2495 main.log.debug( self.name + ": intent ID - " + intentID +
2496 " expected state is " + intentDict[ intentID ] +
2497 " but actual state is " + intentDictONOS[ intentID ] )
2498 returnValue = main.FALSE
2499 intentDictONOS.pop( intentID )
2500 if len( intentDictONOS ) > 0:
2501 returnValue = main.FALSE
2502 for intentID in intentDictONOS.keys():
2503 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002504 if returnValue == main.TRUE:
2505 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2506 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002507 except KeyError:
2508 main.log.exception( self.name + ": KeyError exception found" )
2509 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002510 except ( TypeError, ValueError ):
2511 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002512 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002513 except pexpect.EOF:
2514 main.log.error( self.name + ": EOF exception found" )
2515 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002516 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002517 except Exception:
2518 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002519 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002520
YPZhang14a4aa92016-07-15 13:37:15 -07002521 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002522 """
2523 Description:
2524 Check the number of installed intents.
2525 Optional:
2526 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002527 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002528 Return:
2529 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2530 , otherwise, returns main.FALSE.
2531 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002532
GlennRCed771242016-01-13 17:02:47 -08002533 try:
2534 cmd = "intents -s -j"
2535
2536 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002537 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002538 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002539 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002540 response = json.loads( response )
2541
2542 # get total and installed number, see if they are match
2543 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002544 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002545 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2546 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002547 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002548 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2549 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002550 return main.FALSE
2551
Jon Hallc6793552016-01-19 14:18:37 -08002552 except ( TypeError, ValueError ):
2553 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002554 return None
2555 except pexpect.EOF:
2556 main.log.error( self.name + ": EOF exception found" )
2557 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002558 if noExit:
2559 return main.FALSE
2560 else:
Devin Lim44075962017-08-11 10:56:37 -07002561 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002562 except pexpect.TIMEOUT:
2563 main.log.error( self.name + ": ONOS timeout" )
2564 return None
GlennRCed771242016-01-13 17:02:47 -08002565 except Exception:
2566 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002567 if noExit:
2568 return main.FALSE
2569 else:
Devin Lim44075962017-08-11 10:56:37 -07002570 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002571
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002572 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002573 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002574 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002575 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002576 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002577 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002578 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002579 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002580 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002581 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002582 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002583 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002584 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002585 cmdStr += " -n"
2586 cmdStr += " " + state
2587 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002588 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002589 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002590 assert "Command not found:" not in handle, handle
2591 if re.search( "Error:", handle ):
2592 main.log.error( self.name + ": flows() response: " +
2593 str( handle ) )
2594 return handle
2595 except AssertionError:
2596 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002597 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002598 except TypeError:
2599 main.log.exception( self.name + ": Object not as expected" )
2600 return None
Jon Hallc6793552016-01-19 14:18:37 -08002601 except pexpect.TIMEOUT:
2602 main.log.error( self.name + ": ONOS timeout" )
2603 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002604 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002605 main.log.error( self.name + ": EOF exception found" )
2606 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002607 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002608 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002609 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002610 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002611
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002612 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002613 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002614 count = int( count ) if count else 0
2615 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002616
Jon Halle0f0b342017-04-18 11:43:47 -07002617 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002618 """
2619 Description:
GlennRCed771242016-01-13 17:02:47 -08002620 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002621 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2622 if the count of those states is 0, which means all current flows
2623 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002624 Optional:
GlennRCed771242016-01-13 17:02:47 -08002625 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002626 Return:
2627 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002628 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002629 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002630 """
2631 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002632 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002633 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002634 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002635 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002636 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002637 if rawFlows:
2638 # if we didn't get flows or flows function return None, we should return
2639 # main.Flase
2640 checkedStates.append( json.loads( rawFlows ) )
2641 else:
2642 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002643 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002644 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002645 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002646 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002647 except TypeError:
2648 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002649 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002650
GlennRCed771242016-01-13 17:02:47 -08002651 # We want to count PENDING_ADD if isPENDING is true
2652 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002653 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002654 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002655 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002656 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002657 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002658 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002659 except ( TypeError, ValueError ):
2660 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002661 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002662
YPZhang240842b2016-05-17 12:00:50 -07002663 except AssertionError:
2664 main.log.exception( "" )
2665 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002666 except pexpect.TIMEOUT:
2667 main.log.error( self.name + ": ONOS timeout" )
2668 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002669 except pexpect.EOF:
2670 main.log.error( self.name + ": EOF exception found" )
2671 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002672 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002673 except Exception:
2674 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002675 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002676
GlennRCed771242016-01-13 17:02:47 -08002677 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002678 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002679 """
andrewonlab87852b02014-11-19 18:44:19 -05002680 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002681 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002682 a specific point-to-point intent definition
2683 Required:
GlennRCed771242016-01-13 17:02:47 -08002684 * ingress: specify source dpid
2685 * egress: specify destination dpid
2686 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002687 Optional:
GlennRCed771242016-01-13 17:02:47 -08002688 * offset: the keyOffset is where the next batch of intents
2689 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002690 * noExit: If set to True, TestON will not exit if any error when issus command
2691 * getResponse: If set to True, function will return ONOS response.
2692
GlennRCed771242016-01-13 17:02:47 -08002693 Returns: If failed to push test intents, it will returen None,
2694 if successful, return true.
2695 Timeout expection will return None,
2696 TypeError will return false
2697 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002698 """
andrewonlab87852b02014-11-19 18:44:19 -05002699 try:
GlennRCed771242016-01-13 17:02:47 -08002700 if background:
2701 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002702 else:
GlennRCed771242016-01-13 17:02:47 -08002703 back = ""
2704 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002705 ingress,
2706 egress,
2707 batchSize,
2708 offset,
2709 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002710 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002711 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002712 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002713 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002714 if getResponse:
2715 return response
2716
GlennRCed771242016-01-13 17:02:47 -08002717 # TODO: We should handle if there is failure in installation
2718 return main.TRUE
2719
Jon Hallc6793552016-01-19 14:18:37 -08002720 except AssertionError:
2721 main.log.exception( "" )
2722 return None
GlennRCed771242016-01-13 17:02:47 -08002723 except pexpect.TIMEOUT:
2724 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002725 return None
andrewonlab87852b02014-11-19 18:44:19 -05002726 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002727 main.log.error( self.name + ": EOF exception found" )
2728 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002729 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002730 except TypeError:
2731 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002732 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002733 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002734 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002735 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002736
YPZhangebf9eb52016-05-12 15:20:24 -07002737 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002738 """
2739 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002740 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002741 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002742 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002743 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002744 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002745
YPZhangb5d3f832016-01-23 22:54:26 -08002746 try:
YPZhange3109a72016-02-02 11:25:37 -08002747 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002748 cmd = "flows -c added"
2749 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2750 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002751 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002752 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002753 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002754 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002755 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002756 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002757 return None
2758 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002759
You Wangd3cb2ce2016-05-16 14:01:24 -07002760 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002761 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002762 return None
2763 except pexpect.EOF:
2764 main.log.error( self.name + ": EOF exception found" )
2765 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002766 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002767 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002768 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002769 except pexpect.TIMEOUT:
2770 main.log.error( self.name + ": ONOS timeout" )
2771 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002772 except Exception:
2773 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002774 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002775 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002776 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002777
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002778 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002779 """
2780 Description:
2781 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002782 Optional:
2783 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002784 Return:
2785 The number of intents
2786 """
2787 try:
2788 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002789 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002790 if response is None:
2791 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002792 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002793 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002794 except ( TypeError, ValueError ):
2795 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002796 return None
2797 except pexpect.EOF:
2798 main.log.error( self.name + ": EOF exception found" )
2799 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002800 if noExit:
2801 return -1
2802 else:
Devin Lim44075962017-08-11 10:56:37 -07002803 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002804 except Exception:
2805 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002806 if noExit:
2807 return -1
2808 else:
Devin Lim44075962017-08-11 10:56:37 -07002809 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002810
kelvin-onlabd3b64892015-01-20 13:26:24 -08002811 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002812 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002813 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002814 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002815 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002816 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002817 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002818 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002819 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002820 cmdStr += " -j"
2821 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002822 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002823 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002824 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002825 except AssertionError:
2826 main.log.exception( "" )
2827 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002828 except TypeError:
2829 main.log.exception( self.name + ": Object not as expected" )
2830 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002831 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002832 main.log.error( self.name + ": EOF exception found" )
2833 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002834 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002835 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002836 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002837 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002838
kelvin-onlabd3b64892015-01-20 13:26:24 -08002839 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002840 """
2841 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002842 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002843 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002844 """
andrewonlab867212a2014-10-22 20:13:38 -04002845 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002846 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002847 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002848 cmdStr += " -j"
2849 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002850 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002851 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002852 if handle:
2853 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002854 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002855 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002856 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002857 else:
2858 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002859 except AssertionError:
2860 main.log.exception( "" )
2861 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002862 except TypeError:
2863 main.log.exception( self.name + ": Object not as expected" )
2864 return None
andrewonlab867212a2014-10-22 20:13:38 -04002865 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002866 main.log.error( self.name + ": EOF exception found" )
2867 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002868 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002869 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002870 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002871 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002872
kelvin8ec71442015-01-15 16:57:00 -08002873 # Wrapper functions ****************
2874 # Wrapper functions use existing driver
2875 # functions and extends their use case.
2876 # For example, we may use the output of
2877 # a normal driver function, and parse it
2878 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002879
kelvin-onlabd3b64892015-01-20 13:26:24 -08002880 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002881 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002882 Description:
2883 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002884 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002885 try:
kelvin8ec71442015-01-15 16:57:00 -08002886 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002887 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002888 if intentsStr is None:
2889 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002890 # Convert to a dictionary
2891 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002892 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002893 for intent in intents:
2894 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002895 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002896 except TypeError:
2897 main.log.exception( self.name + ": Object not as expected" )
2898 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002899 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002900 main.log.error( self.name + ": EOF exception found" )
2901 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002902 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002903 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002904 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002905 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002906
You Wang3c276252016-09-21 15:21:36 -07002907 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002908 """
2909 Determine the number of flow rules for the given device id that are
2910 in the added state
You Wang3c276252016-09-21 15:21:36 -07002911 Params:
2912 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002913 """
2914 try:
You Wang3c276252016-09-21 15:21:36 -07002915 if core:
2916 cmdStr = "flows any " + str( deviceId ) + " | " +\
2917 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2918 else:
2919 cmdStr = "flows any " + str( deviceId ) + " | " +\
2920 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002921 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002922 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002923 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002924 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002925 except AssertionError:
2926 main.log.exception( "" )
2927 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002928 except pexpect.EOF:
2929 main.log.error( self.name + ": EOF exception found" )
2930 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002931 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002932 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002933 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002934 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002935
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002936 def groupAddedCount( self, deviceId, core=False ):
2937 """
2938 Determine the number of group rules for the given device id that are
2939 in the added state
2940 Params:
2941 core: if True, only return the number of core groups added
2942 """
2943 try:
2944 if core:
2945 cmdStr = "groups any " + str( deviceId ) + " | " +\
2946 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2947 else:
2948 cmdStr = "groups any " + str( deviceId ) + " | " +\
2949 "grep 'state=ADDED' | wc -l"
2950 handle = self.sendline( cmdStr )
2951 assert handle is not None, "Error in sendline"
2952 assert "Command not found:" not in handle, handle
2953 return handle
2954 except AssertionError:
2955 main.log.exception( "" )
2956 return None
2957 except pexpect.EOF:
2958 main.log.error( self.name + ": EOF exception found" )
2959 main.log.error( self.name + ": " + self.handle.before )
2960 main.cleanAndExit()
2961 except Exception:
2962 main.log.exception( self.name + ": Uncaught exception!" )
2963 main.cleanAndExit()
2964
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002965 def addStaticRoute( self, subnet, intf):
2966 """
2967 Adds a static route to onos.
2968 Params:
2969 subnet: The subnet reaching through this route
2970 intf: The interface this route is reachable through
2971 """
2972 try:
2973 cmdStr = "route-add " + subnet + " " + intf
2974 handle = self.sendline( cmdStr )
2975 assert handle is not None, "Error in sendline"
2976 assert "Command not found:" not in handle, handle
2977 return handle
2978 except AssertionError:
2979 main.log.exception( "" )
2980 return None
2981 except pexpect.EOF:
2982 main.log.error( self.name + ": EOF exception found" )
2983 main.log.error( self.name + ": " + self.handle.before )
2984 main.cleanAndExit()
2985 except Exception:
2986 main.log.exception( self.name + ": Uncaught exception!" )
2987 main.cleanAndExit()
2988
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002989 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
2990 """
2991 Description:
2992 Check whether the number of groups for the given device id that
2993 are in ADDED state is bigger than minGroupCount.
2994 Required:
2995 * deviceId: device id to check the number of added group rules
2996 Optional:
2997 * minGroupCount: the number of groups to compare
2998 * core: if True, only check the number of core groups added
2999 * comparison: if 0, compare with greater than minFlowCount
3000 * if 1, compare with equal to minFlowCount
3001 Return:
3002 Returns the number of groups if it is bigger than minGroupCount,
3003 returns main.FALSE otherwise.
3004 """
3005 count = self.groupAddedCount( deviceId, core )
3006 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003007 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003008 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
3009
You Wangc02f3be2018-05-18 12:14:23 -07003010 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003011 """
3012 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07003013 deviceId: Id of the device from which we retrieve groups
3014 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003015 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003016 try:
You Wangc02f3be2018-05-18 12:14:23 -07003017 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
3018 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003019 assert handle is not None, "Error in sendline"
3020 assert "Command not found:" not in handle, handle
3021 return handle
3022 except AssertionError:
3023 main.log.exception( "" )
3024 return None
3025 except TypeError:
3026 main.log.exception( self.name + ": Object not as expected" )
3027 return None
3028 except pexpect.EOF:
3029 main.log.error( self.name + ": EOF exception found" )
3030 main.log.error( self.name + ": " + self.handle.before )
3031 main.cleanAndExit()
3032 except Exception:
3033 main.log.exception( self.name + ": Uncaught exception!" )
3034 main.cleanAndExit()
3035
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003036 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003037 """
3038 Description:
3039 Check whether the number of flow rules for the given device id that
3040 are in ADDED state is bigger than minFlowCount.
3041 Required:
3042 * deviceId: device id to check the number of added flow rules
3043 Optional:
3044 * minFlowCount: the number of flow rules to compare
3045 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003046 * comparison: if 0, compare with greater than minFlowCount
3047 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003048 Return:
3049 Returns the number of flow rules if it is bigger than minFlowCount,
3050 returns main.FALSE otherwise.
3051 """
3052 count = self.flowAddedCount( deviceId, core )
3053 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003054 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003055 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003056
kelvin-onlabd3b64892015-01-20 13:26:24 -08003057 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003058 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003059 Use 'devices' function to obtain list of all devices
3060 and parse the result to obtain a list of all device
3061 id's. Returns this list. Returns empty list if no
3062 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003063 List is ordered sequentially
3064
andrewonlab3e15ead2014-10-15 14:21:34 -04003065 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003066 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003067 the ids. By obtaining the list of device ids on the fly,
3068 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003069 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003070 try:
kelvin8ec71442015-01-15 16:57:00 -08003071 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003072 devicesStr = self.devices( jsonFormat=False )
3073 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003074
kelvin-onlabd3b64892015-01-20 13:26:24 -08003075 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003076 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003077 return idList
kelvin8ec71442015-01-15 16:57:00 -08003078
3079 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003080 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003081 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003082 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003083 # Split list further into arguments before and after string
3084 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003085 # append to idList
3086 for arg in tempList:
3087 idList.append( arg.split( "id=" )[ 1 ] )
3088 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003089
Jon Halld4d4b372015-01-28 16:02:41 -08003090 except TypeError:
3091 main.log.exception( self.name + ": Object not as expected" )
3092 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003093 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003094 main.log.error( self.name + ": EOF exception found" )
3095 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003096 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003097 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003098 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003099 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003100
kelvin-onlabd3b64892015-01-20 13:26:24 -08003101 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003102 """
andrewonlab7c211572014-10-15 16:45:20 -04003103 Uses 'nodes' function to obtain list of all nodes
3104 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003105 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003106 Returns:
3107 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003108 """
andrewonlab7c211572014-10-15 16:45:20 -04003109 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003110 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003111 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003112 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003113 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003114 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003115 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003116 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003117 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003118 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003119 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003120 except ( TypeError, ValueError ):
3121 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003122 return None
andrewonlab7c211572014-10-15 16:45:20 -04003123 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003124 main.log.error( self.name + ": EOF exception found" )
3125 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003126 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003127 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003128 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003129 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003130
kelvin-onlabd3b64892015-01-20 13:26:24 -08003131 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003132 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003133 Return the first device from the devices api whose 'id' contains 'dpid'
3134 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003135 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003136 try:
kelvin8ec71442015-01-15 16:57:00 -08003137 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003138 return None
3139 else:
kelvin8ec71442015-01-15 16:57:00 -08003140 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003141 rawDevices = self.devices()
3142 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003143 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003144 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003145 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3146 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003147 return device
3148 return None
Jon Hallc6793552016-01-19 14:18:37 -08003149 except ( TypeError, ValueError ):
3150 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003151 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003152 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003153 main.log.error( self.name + ": EOF exception found" )
3154 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003155 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003156 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003157 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003158 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003159
You Wang24139872016-05-03 11:48:47 -07003160 def getTopology( self, topologyOutput ):
3161 """
3162 Definition:
3163 Loads a json topology output
3164 Return:
3165 topology = current ONOS topology
3166 """
3167 import json
3168 try:
3169 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003170 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003171 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003172 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003173 except ( TypeError, ValueError ):
3174 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3175 return None
You Wang24139872016-05-03 11:48:47 -07003176 except pexpect.EOF:
3177 main.log.error( self.name + ": EOF exception found" )
3178 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003179 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003180 except Exception:
3181 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003182 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003183
Pier6a0c4de2018-03-18 16:01:30 -07003184 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003185 """
Jon Hallefbd9792015-03-05 16:11:36 -08003186 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003187 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003188 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003189
Flavio Castro82ee2f62016-06-07 15:04:12 -07003190 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003191 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003192 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003193 logLevel = level to log to.
3194 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003195
Jon Hallefbd9792015-03-05 16:11:36 -08003196 Returns: main.TRUE if the number of switches and links are correct,
3197 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003198 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003199 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003200 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003201 try:
You Wang13310252016-07-31 10:56:14 -07003202 summary = self.summary()
3203 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003204 except ( TypeError, ValueError ):
3205 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3206 return main.ERROR
3207 try:
3208 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003209 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003210 return main.ERROR
3211 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003212 # Is the number of switches is what we expected
3213 devices = topology.get( 'devices', False )
3214 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003215 nodes = summary.get( 'nodes', False )
3216 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003217 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003218 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003219 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003220 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003221 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3222 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003223 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003224 output = output + "The number of links and switches match "\
3225 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003226 result = main.TRUE
3227 else:
You Wang24139872016-05-03 11:48:47 -07003228 output = output + \
3229 "The number of links and switches does not match " + \
3230 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003231 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003232 output = output + "\n ONOS sees %i devices" % int( devices )
3233 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003234 if int( numolink ) > 0:
3235 output = output + "and %i links " % int( links )
3236 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003237 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003238 output = output + "and %i controllers " % int( nodes )
3239 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003240 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003241 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003242 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003243 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003244 else:
You Wang24139872016-05-03 11:48:47 -07003245 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003246 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003247 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003248 main.log.error( self.name + ": EOF exception found" )
3249 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003250 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003251 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003252 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003253 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003254
kelvin-onlabd3b64892015-01-20 13:26:24 -08003255 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003256 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003257 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003258 deviceId must be the id of a device as seen in the onos devices command
3259 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003260 role must be either master, standby, or none
3261
Jon Halle3f39ff2015-01-13 11:50:53 -08003262 Returns:
3263 main.TRUE or main.FALSE based on argument verification and
3264 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003265 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003266 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003267 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003268 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003269 cmdStr = "device-role " +\
3270 str( deviceId ) + " " +\
3271 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003272 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003273 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003274 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003275 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003276 if re.search( "Error", handle ):
3277 # end color output to escape any colours
3278 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003279 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003280 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003281 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003282 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003283 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003284 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003285 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003286 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003287 except AssertionError:
3288 main.log.exception( "" )
3289 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003290 except TypeError:
3291 main.log.exception( self.name + ": Object not as expected" )
3292 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003293 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003294 main.log.error( self.name + ": EOF exception found" )
3295 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003296 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003297 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003298 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003299 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003300
kelvin-onlabd3b64892015-01-20 13:26:24 -08003301 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003302 """
Jon Hall0dd09952018-04-19 09:59:11 -07003303 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003304 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003305 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003306 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003307 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003308 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003309 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003310 cmdStr += " -j"
3311 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003312 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003313 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003314 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003315 except AssertionError:
3316 main.log.exception( "" )
3317 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003318 except TypeError:
3319 main.log.exception( self.name + ": Object not as expected" )
3320 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003321 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003322 main.log.error( self.name + ": EOF exception found" )
3323 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003324 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003325 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003326 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003327 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003328
kelvin-onlabd3b64892015-01-20 13:26:24 -08003329 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003330 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003331 CLI command to get the current leader for the Election test application
3332 NOTE: Requires installation of the onos-app-election feature
3333 Returns: Node IP of the leader if one exists
3334 None if none exists
3335 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003336 """
Jon Hall94fd0472014-12-08 11:52:42 -08003337 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003338 cmdStr = "election-test-leader"
3339 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003340 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003341 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003342 # Leader
3343 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003344 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003345 nodeSearch = re.search( leaderPattern, response )
3346 if nodeSearch:
3347 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003348 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003349 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003350 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003351 # no leader
3352 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003353 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003354 nullSearch = re.search( nullPattern, response )
3355 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003356 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003357 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003358 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003359 # error
Jon Hall0e240372018-05-02 11:21:57 -07003360 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003361 ": " + "unexpected response" )
3362 main.log.error( repr( response ) )
3363 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003364 except AssertionError:
3365 main.log.exception( "" )
3366 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003367 except TypeError:
3368 main.log.exception( self.name + ": Object not as expected" )
3369 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003370 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003371 main.log.error( self.name + ": EOF exception found" )
3372 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003373 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003374 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003375 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003376 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003377
kelvin-onlabd3b64892015-01-20 13:26:24 -08003378 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003379 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003380 CLI command to run for leadership of the Election test application.
3381 NOTE: Requires installation of the onos-app-election feature
3382 Returns: Main.TRUE on success
3383 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003384 """
Jon Hall94fd0472014-12-08 11:52:42 -08003385 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003386 cmdStr = "election-test-run"
3387 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003388 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003389 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003390 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003391 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003392 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003393 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003394 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003395 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003396 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003397 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003398 # error
Jon Hall0e240372018-05-02 11:21:57 -07003399 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003400 ": " + "unexpected response" )
3401 main.log.error( repr( response ) )
3402 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003403 except AssertionError:
3404 main.log.exception( "" )
3405 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003406 except TypeError:
3407 main.log.exception( self.name + ": Object not as expected" )
3408 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003409 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003410 main.log.error( self.name + ": EOF exception found" )
3411 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003412 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003413 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003414 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003415 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003416
kelvin-onlabd3b64892015-01-20 13:26:24 -08003417 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003418 """
Jon Hall94fd0472014-12-08 11:52:42 -08003419 * CLI command to withdraw the local node from leadership election for
3420 * the Election test application.
3421 #NOTE: Requires installation of the onos-app-election feature
3422 Returns: Main.TRUE on success
3423 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003424 """
Jon Hall94fd0472014-12-08 11:52:42 -08003425 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003426 cmdStr = "election-test-withdraw"
3427 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003428 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003429 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003430 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003431 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003432 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003433 if re.search( successPattern, response ):
3434 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003435 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003436 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003437 # error
Jon Hall0e240372018-05-02 11:21:57 -07003438 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003439 self.name + ": " + "unexpected response" )
3440 main.log.error( repr( response ) )
3441 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003442 except AssertionError:
3443 main.log.exception( "" )
3444 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003445 except TypeError:
3446 main.log.exception( self.name + ": Object not as expected" )
3447 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003448 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003449 main.log.error( self.name + ": EOF exception found" )
3450 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003451 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003452 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003453 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003454 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003455
kelvin8ec71442015-01-15 16:57:00 -08003456 def getDevicePortsEnabledCount( self, dpid ):
3457 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003458 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003459 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003460 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003461 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003462 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3463 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003464 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003465 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003466 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003467 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003468 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003469 return output
Jon Hallc6793552016-01-19 14:18:37 -08003470 except AssertionError:
3471 main.log.exception( "" )
3472 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003473 except TypeError:
3474 main.log.exception( self.name + ": Object not as expected" )
3475 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003476 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003477 main.log.error( self.name + ": EOF exception found" )
3478 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003479 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003480 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003481 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003482 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003483
kelvin8ec71442015-01-15 16:57:00 -08003484 def getDeviceLinksActiveCount( self, dpid ):
3485 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003486 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003487 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003488 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003489 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003490 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3491 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003492 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003493 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003494 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003495 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003496 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003497 return output
Jon Hallc6793552016-01-19 14:18:37 -08003498 except AssertionError:
3499 main.log.exception( "" )
3500 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003501 except TypeError:
3502 main.log.exception( self.name + ": Object not as expected" )
3503 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003504 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003505 main.log.error( self.name + ": EOF exception found" )
3506 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003507 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003508 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003509 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003510 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003511
kelvin8ec71442015-01-15 16:57:00 -08003512 def getAllIntentIds( self ):
3513 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003514 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003515 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003516 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003517 cmdStr = "onos:intents | grep id="
3518 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003519 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003520 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003521 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003522 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003523 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003524 return output
Jon Hallc6793552016-01-19 14:18:37 -08003525 except AssertionError:
3526 main.log.exception( "" )
3527 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003528 except TypeError:
3529 main.log.exception( self.name + ": Object not as expected" )
3530 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003531 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003532 main.log.error( self.name + ": EOF exception found" )
3533 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003534 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003535 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003536 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003537 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003538
Jon Hall73509952015-02-24 16:42:56 -08003539 def intentSummary( self ):
3540 """
Jon Hallefbd9792015-03-05 16:11:36 -08003541 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003542 """
3543 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003544 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003545 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003546 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003547 states.append( intent.get( 'state', None ) )
3548 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003549 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003550 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003551 except ( TypeError, ValueError ):
3552 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003553 return None
3554 except pexpect.EOF:
3555 main.log.error( self.name + ": EOF exception found" )
3556 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003557 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003558 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003559 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003560 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003561
Jon Hall61282e32015-03-19 11:34:11 -07003562 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003563 """
3564 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003565 Optional argument:
3566 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003567 """
Jon Hall63604932015-02-26 17:09:50 -08003568 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003569 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003570 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003571 cmdStr += " -j"
3572 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003573 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003574 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003575 return output
Jon Hallc6793552016-01-19 14:18:37 -08003576 except AssertionError:
3577 main.log.exception( "" )
3578 return None
Jon Hall63604932015-02-26 17:09:50 -08003579 except TypeError:
3580 main.log.exception( self.name + ": Object not as expected" )
3581 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003582 except pexpect.EOF:
3583 main.log.error( self.name + ": EOF exception found" )
3584 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003585 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003586 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003587 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003588 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003589
acsmarsa4a4d1e2015-07-10 16:01:24 -07003590 def leaderCandidates( self, jsonFormat=True ):
3591 """
3592 Returns the output of the leaders -c command.
3593 Optional argument:
3594 * jsonFormat - boolean indicating if you want output in json
3595 """
3596 try:
3597 cmdStr = "onos:leaders -c"
3598 if jsonFormat:
3599 cmdStr += " -j"
3600 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003601 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003602 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003603 return output
Jon Hallc6793552016-01-19 14:18:37 -08003604 except AssertionError:
3605 main.log.exception( "" )
3606 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003607 except TypeError:
3608 main.log.exception( self.name + ": Object not as expected" )
3609 return None
3610 except pexpect.EOF:
3611 main.log.error( self.name + ": EOF exception found" )
3612 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003613 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003614 except Exception:
3615 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003616 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003617
Jon Hallc6793552016-01-19 14:18:37 -08003618 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003619 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003620 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003621 topic parameter and an empty list if the topic doesn't exist
3622 If no leader is elected leader in the returned list will be "none"
3623 Returns None if there is a type error processing the json object
3624 """
3625 try:
Jon Hall6e709752016-02-01 13:38:46 -08003626 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003627 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003628 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003629 assert "Command not found:" not in rawOutput, rawOutput
3630 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003631 results = []
3632 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003633 if dict[ "topic" ] == topic:
3634 leader = dict[ "leader" ]
3635 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003636 results.append( leader )
3637 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003638 return results
Jon Hallc6793552016-01-19 14:18:37 -08003639 except AssertionError:
3640 main.log.exception( "" )
3641 return None
3642 except ( TypeError, ValueError ):
3643 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01: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()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003649 except Exception:
3650 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003651 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003652
Jon Hall61282e32015-03-19 11:34:11 -07003653 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003654 """
3655 Returns the output of the intent Pending map.
3656 """
Jon Hall63604932015-02-26 17:09:50 -08003657 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003658 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003659 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003660 cmdStr += " -j"
3661 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003662 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003663 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003664 return output
Jon Hallc6793552016-01-19 14:18:37 -08003665 except AssertionError:
3666 main.log.exception( "" )
3667 return None
Jon Hall63604932015-02-26 17:09:50 -08003668 except TypeError:
3669 main.log.exception( self.name + ": Object not as expected" )
3670 return None
3671 except pexpect.EOF:
3672 main.log.error( self.name + ": EOF exception found" )
3673 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003674 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003675 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003676 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003677 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003678
Jon Hall2c8959e2016-12-16 12:17:34 -08003679 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003680 """
3681 Returns the output of the raft partitions command for ONOS.
3682 """
Jon Hall61282e32015-03-19 11:34:11 -07003683 # Sample JSON
3684 # {
3685 # "leader": "tcp://10.128.30.11:7238",
3686 # "members": [
3687 # "tcp://10.128.30.11:7238",
3688 # "tcp://10.128.30.17:7238",
3689 # "tcp://10.128.30.13:7238",
3690 # ],
3691 # "name": "p1",
3692 # "term": 3
3693 # },
Jon Hall63604932015-02-26 17:09:50 -08003694 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003695 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003696 if candidates:
3697 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003698 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003699 cmdStr += " -j"
3700 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003701 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003702 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003703 return output
Jon Hallc6793552016-01-19 14:18:37 -08003704 except AssertionError:
3705 main.log.exception( "" )
3706 return None
Jon Hall63604932015-02-26 17:09:50 -08003707 except TypeError:
3708 main.log.exception( self.name + ": Object not as expected" )
3709 return None
3710 except pexpect.EOF:
3711 main.log.error( self.name + ": EOF exception found" )
3712 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003713 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003714 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003715 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003716 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003717
Jon Halle9f909e2016-09-23 10:43:12 -07003718 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003719 """
3720 Returns the output of the apps command for ONOS. This command lists
3721 information about installed ONOS applications
3722 """
3723 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003724 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003725 # "description":"ONOS OpenFlow protocol southbound providers",
3726 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003727 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003728 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003729 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003730 if summary:
3731 cmdStr += " -s"
3732 if active:
3733 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003734 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003735 cmdStr += " -j"
3736 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003737 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003738 assert "Command not found:" not in output, output
3739 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003740 return output
Jon Hallbe379602015-03-24 13:39:32 -07003741 # FIXME: look at specific exceptions/Errors
3742 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003743 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003744 return None
3745 except TypeError:
3746 main.log.exception( self.name + ": Object not as expected" )
3747 return None
3748 except pexpect.EOF:
3749 main.log.error( self.name + ": EOF exception found" )
3750 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003751 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003752 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003753 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003754 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003755
You Wangcdc51fe2018-08-12 17:14:56 -07003756 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003757 """
3758 Uses the onos:apps cli command to return the status of an application.
3759 Returns:
3760 "ACTIVE" - If app is installed and activated
3761 "INSTALLED" - If app is installed and deactivated
3762 "UNINSTALLED" - If app is not installed
3763 None - on error
3764 """
Jon Hall146f1522015-03-24 15:33:24 -07003765 try:
3766 if not isinstance( appName, types.StringType ):
3767 main.log.error( self.name + ".appStatus(): appName must be" +
3768 " a string" )
3769 return None
3770 output = self.apps( jsonFormat=True )
3771 appsJson = json.loads( output )
3772 state = None
3773 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003774 if appName == app.get( 'name' ):
3775 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003776 break
3777 if state == "ACTIVE" or state == "INSTALLED":
3778 return state
3779 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003780 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003781 return "UNINSTALLED"
3782 elif state:
3783 main.log.error( "Unexpected state from 'onos:apps': " +
3784 str( state ) )
3785 return state
Jon Hallc6793552016-01-19 14:18:37 -08003786 except ( TypeError, ValueError ):
3787 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003788 return None
3789 except pexpect.EOF:
3790 main.log.error( self.name + ": EOF exception found" )
3791 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003792 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003793 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003794 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003795 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003796
Jon Hallbe379602015-03-24 13:39:32 -07003797 def app( self, appName, option ):
3798 """
3799 Interacts with the app command for ONOS. This command manages
3800 application inventory.
3801 """
Jon Hallbe379602015-03-24 13:39:32 -07003802 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003803 # Validate argument types
3804 valid = True
3805 if not isinstance( appName, types.StringType ):
3806 main.log.error( self.name + ".app(): appName must be a " +
3807 "string" )
3808 valid = False
3809 if not isinstance( option, types.StringType ):
3810 main.log.error( self.name + ".app(): option must be a string" )
3811 valid = False
3812 if not valid:
3813 return main.FALSE
3814 # Validate Option
3815 option = option.lower()
3816 # NOTE: Install may become a valid option
3817 if option == "activate":
3818 pass
3819 elif option == "deactivate":
3820 pass
3821 elif option == "uninstall":
3822 pass
3823 else:
3824 # Invalid option
3825 main.log.error( "The ONOS app command argument only takes " +
3826 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003827 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003828 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003829 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003830 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003831 assert output is not None, "Error in sendline"
3832 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003833 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003834 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003835 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003836 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003837 elif "No such application" in output:
3838 main.log.error( "The application '" + appName +
3839 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003840 return main.FALSE
3841 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003842 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003843 str( output ) )
3844 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003845 elif "Unsupported command:" in output:
3846 main.log.error( "Incorrect command given to 'app': " +
3847 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003848 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003849 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003850 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003851 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003852 except AssertionError:
3853 main.log.exception( self.name + ": AssertionError exception found" )
3854 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003855 except TypeError:
3856 main.log.exception( self.name + ": Object not as expected" )
3857 return main.ERROR
3858 except pexpect.EOF:
3859 main.log.error( self.name + ": EOF exception found" )
3860 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003861 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003862 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003863 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003864 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003865
Jon Hallbd16b922015-03-26 17:53:15 -07003866 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003867 """
3868 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003869 appName is the hierarchical app name, not the feature name
3870 If check is True, method will check the status of the app after the
3871 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003872 Returns main.TRUE if the command was successfully sent
3873 main.FALSE if the cli responded with an error or given
3874 incorrect input
3875 """
3876 try:
3877 if not isinstance( appName, types.StringType ):
3878 main.log.error( self.name + ".activateApp(): appName must be" +
3879 " a string" )
3880 return main.FALSE
3881 status = self.appStatus( appName )
3882 if status == "INSTALLED":
3883 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003884 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003885 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003886 status = self.appStatus( appName )
3887 if status == "ACTIVE":
3888 return main.TRUE
3889 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003890 main.log.debug( "The state of application " +
3891 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003892 time.sleep( 1 )
3893 return main.FALSE
3894 else: # not 'check' or command didn't succeed
3895 return response
Jon Hall146f1522015-03-24 15:33:24 -07003896 elif status == "ACTIVE":
3897 return main.TRUE
3898 elif status == "UNINSTALLED":
3899 main.log.error( self.name + ": Tried to activate the " +
3900 "application '" + appName + "' which is not " +
3901 "installed." )
3902 else:
3903 main.log.error( "Unexpected return value from appStatus: " +
3904 str( status ) )
3905 return main.ERROR
3906 except TypeError:
3907 main.log.exception( self.name + ": Object not as expected" )
3908 return main.ERROR
3909 except pexpect.EOF:
3910 main.log.error( self.name + ": EOF exception found" )
3911 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003912 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003913 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003914 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003915 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003916
Jon Hallbd16b922015-03-26 17:53:15 -07003917 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003918 """
3919 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003920 appName is the hierarchical app name, not the feature name
3921 If check is True, method will check the status of the app after the
3922 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003923 Returns main.TRUE if the command was successfully sent
3924 main.FALSE if the cli responded with an error or given
3925 incorrect input
3926 """
3927 try:
3928 if not isinstance( appName, types.StringType ):
3929 main.log.error( self.name + ".deactivateApp(): appName must " +
3930 "be a string" )
3931 return main.FALSE
3932 status = self.appStatus( appName )
3933 if status == "INSTALLED":
3934 return main.TRUE
3935 elif status == "ACTIVE":
3936 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003937 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003938 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003939 status = self.appStatus( appName )
3940 if status == "INSTALLED":
3941 return main.TRUE
3942 else:
3943 time.sleep( 1 )
3944 return main.FALSE
3945 else: # not check or command didn't succeed
3946 return response
Jon Hall146f1522015-03-24 15:33:24 -07003947 elif status == "UNINSTALLED":
3948 main.log.warn( self.name + ": Tried to deactivate the " +
3949 "application '" + appName + "' which is not " +
3950 "installed." )
3951 return main.TRUE
3952 else:
3953 main.log.error( "Unexpected return value from appStatus: " +
3954 str( status ) )
3955 return main.ERROR
3956 except TypeError:
3957 main.log.exception( self.name + ": Object not as expected" )
3958 return main.ERROR
3959 except pexpect.EOF:
3960 main.log.error( self.name + ": EOF exception found" )
3961 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003962 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003963 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003964 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003965 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003966
Jon Hallbd16b922015-03-26 17:53:15 -07003967 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003968 """
3969 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003970 appName is the hierarchical app name, not the feature name
3971 If check is True, method will check the status of the app after the
3972 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003973 Returns main.TRUE if the command was successfully sent
3974 main.FALSE if the cli responded with an error or given
3975 incorrect input
3976 """
3977 # TODO: check with Thomas about the state machine for apps
3978 try:
3979 if not isinstance( appName, types.StringType ):
3980 main.log.error( self.name + ".uninstallApp(): appName must " +
3981 "be a string" )
3982 return main.FALSE
3983 status = self.appStatus( appName )
3984 if status == "INSTALLED":
3985 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003986 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003987 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003988 status = self.appStatus( appName )
3989 if status == "UNINSTALLED":
3990 return main.TRUE
3991 else:
3992 time.sleep( 1 )
3993 return main.FALSE
3994 else: # not check or command didn't succeed
3995 return response
Jon Hall146f1522015-03-24 15:33:24 -07003996 elif status == "ACTIVE":
3997 main.log.warn( self.name + ": Tried to uninstall the " +
3998 "application '" + appName + "' which is " +
3999 "currently active." )
4000 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004001 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004002 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004003 status = self.appStatus( appName )
4004 if status == "UNINSTALLED":
4005 return main.TRUE
4006 else:
4007 time.sleep( 1 )
4008 return main.FALSE
4009 else: # not check or command didn't succeed
4010 return response
Jon Hall146f1522015-03-24 15:33:24 -07004011 elif status == "UNINSTALLED":
4012 return main.TRUE
4013 else:
4014 main.log.error( "Unexpected return value from appStatus: " +
4015 str( status ) )
4016 return main.ERROR
4017 except TypeError:
4018 main.log.exception( self.name + ": Object not as expected" )
4019 return main.ERROR
4020 except pexpect.EOF:
4021 main.log.error( self.name + ": EOF exception found" )
4022 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004023 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004024 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004025 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004026 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004027
4028 def appIDs( self, jsonFormat=True ):
4029 """
4030 Show the mappings between app id and app names given by the 'app-ids'
4031 cli command
4032 """
4033 try:
4034 cmdStr = "app-ids"
4035 if jsonFormat:
4036 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004037 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004038 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004039 assert "Command not found:" not in output, output
4040 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004041 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004042 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004043 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004044 return None
4045 except TypeError:
4046 main.log.exception( self.name + ": Object not as expected" )
4047 return None
4048 except pexpect.EOF:
4049 main.log.error( self.name + ": EOF exception found" )
4050 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004051 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004052 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004053 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004054 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004055
4056 def appToIDCheck( self ):
4057 """
4058 This method will check that each application's ID listed in 'apps' is
4059 the same as the ID listed in 'app-ids'. The check will also check that
4060 there are no duplicate IDs issued. Note that an app ID should be
4061 a globaly unique numerical identifier for app/app-like features. Once
4062 an ID is registered, the ID is never freed up so that if an app is
4063 reinstalled it will have the same ID.
4064
4065 Returns: main.TRUE if the check passes and
4066 main.FALSE if the check fails or
4067 main.ERROR if there is some error in processing the test
4068 """
4069 try:
Jon Hall0e240372018-05-02 11:21:57 -07004070 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004071 rawJson = self.appIDs( jsonFormat=True )
4072 if rawJson:
4073 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004074 else:
Jon Hall0e240372018-05-02 11:21:57 -07004075 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4076 return main.FALSE
4077
4078 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004079 rawJson = self.apps( jsonFormat=True )
4080 if rawJson:
4081 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004082 else:
Jon Hallc6793552016-01-19 14:18:37 -08004083 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004084 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004085
Jon Hallbd16b922015-03-26 17:53:15 -07004086 result = main.TRUE
4087 for app in apps:
4088 appID = app.get( 'id' )
4089 if appID is None:
4090 main.log.error( "Error parsing app: " + str( app ) )
4091 result = main.FALSE
4092 appName = app.get( 'name' )
4093 if appName is None:
4094 main.log.error( "Error parsing app: " + str( app ) )
4095 result = main.FALSE
4096 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004097 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004098 if not current: # if ids doesn't have this id
4099 result = main.FALSE
4100 main.log.error( "'app-ids' does not have the ID for " +
4101 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004102 main.log.debug( "apps command returned: " + str( app ) +
4103 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004104 elif len( current ) > 1:
4105 # there is more than one app with this ID
4106 result = main.FALSE
4107 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004108 elif not current[ 0 ][ 'name' ] == appName:
4109 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004110 result = main.FALSE
4111 main.log.error( "'app-ids' has " + str( currentName ) +
4112 " registered under id:" + str( appID ) +
4113 " but 'apps' has " + str( appName ) )
4114 else:
4115 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004116
Jon Hallbd16b922015-03-26 17:53:15 -07004117 # now make sure that app-ids has no duplicates
4118 idsList = []
4119 namesList = []
4120 for item in ids:
4121 idsList.append( item[ 'id' ] )
4122 namesList.append( item[ 'name' ] )
4123 if len( idsList ) != len( set( idsList ) ) or\
4124 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004125 main.log.error( "'app-ids' has some duplicate entries: \n"
4126 + json.dumps( ids,
4127 sort_keys=True,
4128 indent=4,
4129 separators=( ',', ': ' ) ) )
4130 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004131 return result
Jon Hallc6793552016-01-19 14:18:37 -08004132 except ( TypeError, ValueError ):
4133 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004134 return main.ERROR
4135 except pexpect.EOF:
4136 main.log.error( self.name + ": EOF exception found" )
4137 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004138 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004139 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004140 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004141 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004142
Jon Hallfb760a02015-04-13 15:35:03 -07004143 def getCfg( self, component=None, propName=None, short=False,
4144 jsonFormat=True ):
4145 """
4146 Get configuration settings from onos cli
4147 Optional arguments:
4148 component - Optionally only list configurations for a specific
4149 component. If None, all components with configurations
4150 are displayed. Case Sensitive string.
4151 propName - If component is specified, propName option will show
4152 only this specific configuration from that component.
4153 Case Sensitive string.
4154 jsonFormat - Returns output as json. Note that this will override
4155 the short option
4156 short - Short, less verbose, version of configurations.
4157 This is overridden by the json option
4158 returns:
4159 Output from cli as a string or None on error
4160 """
4161 try:
4162 baseStr = "cfg"
4163 cmdStr = " get"
4164 componentStr = ""
4165 if component:
4166 componentStr += " " + component
4167 if propName:
4168 componentStr += " " + propName
4169 if jsonFormat:
4170 baseStr += " -j"
4171 elif short:
4172 baseStr += " -s"
4173 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004174 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004175 assert "Command not found:" not in output, output
4176 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004177 return output
4178 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004179 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004180 return None
4181 except TypeError:
4182 main.log.exception( self.name + ": Object not as expected" )
4183 return None
4184 except pexpect.EOF:
4185 main.log.error( self.name + ": EOF exception found" )
4186 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004187 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004188 except Exception:
4189 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004190 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004191
4192 def setCfg( self, component, propName, value=None, check=True ):
4193 """
4194 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004195 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004196 component - The case sensitive name of the component whose
4197 property is to be set
4198 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004199 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004200 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004201 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004202 check - Boolean, Check whether the option was successfully set this
4203 only applies when a value is given.
4204 returns:
4205 main.TRUE on success or main.FALSE on failure. If check is False,
4206 will return main.TRUE unless there is an error
4207 """
4208 try:
4209 baseStr = "cfg"
4210 cmdStr = " set " + str( component ) + " " + str( propName )
4211 if value is not None:
4212 cmdStr += " " + str( value )
4213 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004214 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004215 assert "Command not found:" not in output, output
4216 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004217 if value and check:
4218 results = self.getCfg( component=str( component ),
4219 propName=str( propName ),
4220 jsonFormat=True )
4221 # Check if current value is what we just set
4222 try:
4223 jsonOutput = json.loads( results )
4224 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004225 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004226 main.log.exception( "Error parsing cfg output" )
4227 main.log.error( "output:" + repr( results ) )
4228 return main.FALSE
4229 if current == str( value ):
4230 return main.TRUE
4231 return main.FALSE
4232 return main.TRUE
4233 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004234 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004235 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004236 except ( TypeError, ValueError ):
4237 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004238 return main.FALSE
4239 except pexpect.EOF:
4240 main.log.error( self.name + ": EOF exception found" )
4241 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004242 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004243 except Exception:
4244 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004245 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004246
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004247 def distPrimitivesSend( self, cmd ):
4248 """
4249 Function to handle sending cli commands for the distributed primitives test app
4250
4251 This command will catch some exceptions and retry the command on some
4252 specific store exceptions.
4253
4254 Required arguments:
4255 cmd - The command to send to the cli
4256 returns:
4257 string containing the cli output
4258 None on Error
4259 """
4260 try:
4261 output = self.sendline( cmd )
4262 try:
4263 assert output is not None, "Error in sendline"
4264 # TODO: Maybe make this less hardcoded
4265 # ConsistentMap Exceptions
4266 assert "org.onosproject.store.service" not in output
4267 # Node not leader
4268 assert "java.lang.IllegalStateException" not in output
4269 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004270 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004271 "command: " + str( output ) )
4272 retryTime = 30 # Conservative time, given by Madan
4273 main.log.info( "Waiting " + str( retryTime ) +
4274 "seconds before retrying." )
4275 time.sleep( retryTime ) # Due to change in mastership
4276 output = self.sendline( cmd )
4277 assert output is not None, "Error in sendline"
4278 assert "Command not found:" not in output, output
4279 assert "Error executing command" not in output, output
4280 main.log.info( self.name + ": " + output )
4281 return output
4282 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004283 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004284 return None
4285 except TypeError:
4286 main.log.exception( self.name + ": Object not as expected" )
4287 return None
4288 except pexpect.EOF:
4289 main.log.error( self.name + ": EOF exception found" )
4290 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004291 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004292 except Exception:
4293 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004294 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004295
Jon Hall390696c2015-05-05 17:13:41 -07004296 def setTestAdd( self, setName, values ):
4297 """
4298 CLI command to add elements to a distributed set.
4299 Arguments:
4300 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004301 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004302 Example usages:
4303 setTestAdd( "set1", "a b c" )
4304 setTestAdd( "set2", "1" )
4305 returns:
4306 main.TRUE on success OR
4307 main.FALSE if elements were already in the set OR
4308 main.ERROR on error
4309 """
4310 try:
4311 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004312 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004313 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4314 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004315 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004316 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004317 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004318 return main.FALSE
4319 else:
4320 main.log.error( self.name + ": setTestAdd did not" +
4321 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004322 main.log.debug( self.name + " actual: " + repr( output ) )
4323 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004324 except TypeError:
4325 main.log.exception( self.name + ": Object not as expected" )
4326 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004327 except Exception:
4328 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004329 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004330
4331 def setTestRemove( self, setName, values, clear=False, retain=False ):
4332 """
4333 CLI command to remove elements from a distributed set.
4334 Required arguments:
4335 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004336 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004337 Optional arguments:
4338 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004339 retain - Retain only the given values. (intersection of the
4340 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004341 returns:
4342 main.TRUE on success OR
4343 main.FALSE if the set was not changed OR
4344 main.ERROR on error
4345 """
4346 try:
4347 cmdStr = "set-test-remove "
4348 if clear:
4349 cmdStr += "-c " + str( setName )
4350 elif retain:
4351 cmdStr += "-r " + str( setName ) + " " + str( values )
4352 else:
4353 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004354 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004355 if clear:
4356 pattern = "Set " + str( setName ) + " cleared"
4357 if re.search( pattern, output ):
4358 return main.TRUE
4359 elif retain:
4360 positivePattern = str( setName ) + " was pruned to contain " +\
4361 "only elements of set \[(.*)\]"
4362 negativePattern = str( setName ) + " was not changed by " +\
4363 "retaining only elements of the set " +\
4364 "\[(.*)\]"
4365 if re.search( positivePattern, output ):
4366 return main.TRUE
4367 elif re.search( negativePattern, output ):
4368 return main.FALSE
4369 else:
4370 positivePattern = "\[(.*)\] was removed from the set " +\
4371 str( setName )
4372 if ( len( values.split() ) == 1 ):
4373 negativePattern = "\[(.*)\] was not in set " +\
4374 str( setName )
4375 else:
4376 negativePattern = "No element of \[(.*)\] was in set " +\
4377 str( setName )
4378 if re.search( positivePattern, output ):
4379 return main.TRUE
4380 elif re.search( negativePattern, output ):
4381 return main.FALSE
4382 main.log.error( self.name + ": setTestRemove did not" +
4383 " match expected output" )
4384 main.log.debug( self.name + " expected: " + pattern )
4385 main.log.debug( self.name + " actual: " + repr( output ) )
4386 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004387 except TypeError:
4388 main.log.exception( self.name + ": Object not as expected" )
4389 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004390 except Exception:
4391 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004392 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004393
4394 def setTestGet( self, setName, values="" ):
4395 """
4396 CLI command to get the elements in a distributed set.
4397 Required arguments:
4398 setName - The name of the set to remove from.
4399 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004400 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004401 returns:
4402 main.ERROR on error OR
4403 A list of elements in the set if no optional arguments are
4404 supplied OR
4405 A tuple containing the list then:
4406 main.FALSE if the given values are not in the set OR
4407 main.TRUE if the given values are in the set OR
4408 """
4409 try:
4410 values = str( values ).strip()
4411 setName = str( setName ).strip()
4412 length = len( values.split() )
4413 containsCheck = None
4414 # Patterns to match
4415 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004416 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004417 containsTrue = "Set " + setName + " contains the value " + values
4418 containsFalse = "Set " + setName + " did not contain the value " +\
4419 values
4420 containsAllTrue = "Set " + setName + " contains the the subset " +\
4421 setPattern
4422 containsAllFalse = "Set " + setName + " did not contain the the" +\
4423 " subset " + setPattern
4424
4425 cmdStr = "set-test-get "
4426 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004427 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004428 if length == 0:
4429 match = re.search( pattern, output )
4430 else: # if given values
4431 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004432 patternTrue = pattern + "\r\n" + containsTrue
4433 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004434 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004435 patternTrue = pattern + "\r\n" + containsAllTrue
4436 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004437 matchTrue = re.search( patternTrue, output )
4438 matchFalse = re.search( patternFalse, output )
4439 if matchTrue:
4440 containsCheck = main.TRUE
4441 match = matchTrue
4442 elif matchFalse:
4443 containsCheck = main.FALSE
4444 match = matchFalse
4445 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004446 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004447 "expected output" )
4448 main.log.debug( self.name + " expected: " + pattern )
4449 main.log.debug( self.name + " actual: " + repr( output ) )
4450 match = None
4451 if match:
4452 setMatch = match.group( 1 )
4453 if setMatch == '':
4454 setList = []
4455 else:
4456 setList = setMatch.split( ", " )
4457 if length > 0:
4458 return ( setList, containsCheck )
4459 else:
4460 return setList
4461 else: # no match
4462 main.log.error( self.name + ": setTestGet did not" +
4463 " match expected output" )
4464 main.log.debug( self.name + " expected: " + pattern )
4465 main.log.debug( self.name + " actual: " + repr( output ) )
4466 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004467 except TypeError:
4468 main.log.exception( self.name + ": Object not as expected" )
4469 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004470 except Exception:
4471 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004472 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004473
4474 def setTestSize( self, setName ):
4475 """
4476 CLI command to get the elements in a distributed set.
4477 Required arguments:
4478 setName - The name of the set to remove from.
4479 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004480 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004481 None on error
4482 """
4483 try:
4484 # TODO: Should this check against the number of elements returned
4485 # and then return true/false based on that?
4486 setName = str( setName ).strip()
4487 # Patterns to match
4488 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004489 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004490 setPattern
4491 cmdStr = "set-test-get -s "
4492 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004493 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004494 if output:
4495 match = re.search( pattern, output )
4496 if match:
4497 setSize = int( match.group( 1 ) )
4498 setMatch = match.group( 2 )
4499 if len( setMatch.split() ) == setSize:
4500 main.log.info( "The size returned by " + self.name +
4501 " matches the number of elements in " +
4502 "the returned set" )
4503 else:
4504 main.log.error( "The size returned by " + self.name +
4505 " does not match the number of " +
4506 "elements in the returned set." )
4507 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004508 else: # no match
4509 main.log.error( self.name + ": setTestGet did not" +
4510 " match expected output" )
4511 main.log.debug( self.name + " expected: " + pattern )
4512 main.log.debug( self.name + " actual: " + repr( output ) )
4513 return None
Jon Hall390696c2015-05-05 17:13:41 -07004514 except TypeError:
4515 main.log.exception( self.name + ": Object not as expected" )
4516 return None
Jon Hall390696c2015-05-05 17:13:41 -07004517 except Exception:
4518 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004519 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004520
Jon Hall80daded2015-05-27 16:07:00 -07004521 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004522 """
4523 Command to list the various counters in the system.
4524 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004525 if jsonFormat, a string of the json object returned by the cli
4526 command
4527 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004528 None on error
4529 """
Jon Hall390696c2015-05-05 17:13:41 -07004530 try:
Jon Hall390696c2015-05-05 17:13:41 -07004531 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004532 if jsonFormat:
4533 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004534 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004535 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004536 assert "Command not found:" not in output, output
4537 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004538 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004539 return output
Jon Hall390696c2015-05-05 17:13:41 -07004540 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004541 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004542 return None
Jon Hall390696c2015-05-05 17:13:41 -07004543 except TypeError:
4544 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004545 return None
Jon Hall390696c2015-05-05 17:13:41 -07004546 except pexpect.EOF:
4547 main.log.error( self.name + ": EOF exception found" )
4548 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004549 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004550 except Exception:
4551 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004552 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004553
Jon Hall935db192016-04-19 00:22:04 -07004554 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004555 """
Jon Halle1a3b752015-07-22 13:02:46 -07004556 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004557 Required arguments:
4558 counter - The name of the counter to increment.
4559 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004560 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004561 returns:
4562 integer value of the counter or
4563 None on Error
4564 """
4565 try:
4566 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004567 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004568 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004569 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004570 if delta != 1:
4571 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004572 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004573 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004574 match = re.search( pattern, output )
4575 if match:
4576 return int( match.group( 1 ) )
4577 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004578 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004579 " match expected output." )
4580 main.log.debug( self.name + " expected: " + pattern )
4581 main.log.debug( self.name + " actual: " + repr( output ) )
4582 return None
Jon Hall390696c2015-05-05 17:13:41 -07004583 except TypeError:
4584 main.log.exception( self.name + ": Object not as expected" )
4585 return None
Jon Hall390696c2015-05-05 17:13:41 -07004586 except Exception:
4587 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004588 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004589
Jon Hall935db192016-04-19 00:22:04 -07004590 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004591 """
4592 CLI command to get a distributed counter then add a delta to it.
4593 Required arguments:
4594 counter - The name of the counter to increment.
4595 Optional arguments:
4596 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004597 returns:
4598 integer value of the counter or
4599 None on Error
4600 """
4601 try:
4602 counter = str( counter )
4603 delta = int( delta )
4604 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004605 cmdStr += counter
4606 if delta != 1:
4607 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004608 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004609 pattern = counter + " was updated to (-?\d+)"
4610 match = re.search( pattern, output )
4611 if match:
4612 return int( match.group( 1 ) )
4613 else:
4614 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4615 " match expected output." )
4616 main.log.debug( self.name + " expected: " + pattern )
4617 main.log.debug( self.name + " actual: " + repr( output ) )
4618 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004619 except TypeError:
4620 main.log.exception( self.name + ": Object not as expected" )
4621 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004622 except Exception:
4623 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004624 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004625
4626 def valueTestGet( self, valueName ):
4627 """
4628 CLI command to get the value of an atomic value.
4629 Required arguments:
4630 valueName - The name of the value to get.
4631 returns:
4632 string value of the value or
4633 None on Error
4634 """
4635 try:
4636 valueName = str( valueName )
4637 cmdStr = "value-test "
4638 operation = "get"
4639 cmdStr = "value-test {} {}".format( valueName,
4640 operation )
4641 output = self.distPrimitivesSend( cmdStr )
4642 pattern = "(\w+)"
4643 match = re.search( pattern, output )
4644 if match:
4645 return match.group( 1 )
4646 else:
4647 main.log.error( self.name + ": valueTestGet did not" +
4648 " match expected output." )
4649 main.log.debug( self.name + " expected: " + pattern )
4650 main.log.debug( self.name + " actual: " + repr( output ) )
4651 return None
4652 except TypeError:
4653 main.log.exception( self.name + ": Object not as expected" )
4654 return None
4655 except Exception:
4656 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004657 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004658
4659 def valueTestSet( self, valueName, newValue ):
4660 """
4661 CLI command to set the value of an atomic value.
4662 Required arguments:
4663 valueName - The name of the value to set.
4664 newValue - The value to assign to the given value.
4665 returns:
4666 main.TRUE on success or
4667 main.ERROR on Error
4668 """
4669 try:
4670 valueName = str( valueName )
4671 newValue = str( newValue )
4672 operation = "set"
4673 cmdStr = "value-test {} {} {}".format( valueName,
4674 operation,
4675 newValue )
4676 output = self.distPrimitivesSend( cmdStr )
4677 if output is not None:
4678 return main.TRUE
4679 else:
4680 return main.ERROR
4681 except TypeError:
4682 main.log.exception( self.name + ": Object not as expected" )
4683 return main.ERROR
4684 except Exception:
4685 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004686 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004687
4688 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4689 """
4690 CLI command to compareAndSet the value of an atomic value.
4691 Required arguments:
4692 valueName - The name of the value.
4693 oldValue - Compare the current value of the atomic value to this
4694 newValue - If the value equals oldValue, set the value to newValue
4695 returns:
4696 main.TRUE on success or
4697 main.FALSE on failure or
4698 main.ERROR on Error
4699 """
4700 try:
4701 valueName = str( valueName )
4702 oldValue = str( oldValue )
4703 newValue = str( newValue )
4704 operation = "compareAndSet"
4705 cmdStr = "value-test {} {} {} {}".format( valueName,
4706 operation,
4707 oldValue,
4708 newValue )
4709 output = self.distPrimitivesSend( cmdStr )
4710 pattern = "(\w+)"
4711 match = re.search( pattern, output )
4712 if match:
4713 result = match.group( 1 )
4714 if result == "true":
4715 return main.TRUE
4716 elif result == "false":
4717 return main.FALSE
4718 else:
4719 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4720 " match expected output." )
4721 main.log.debug( self.name + " expected: " + pattern )
4722 main.log.debug( self.name + " actual: " + repr( output ) )
4723 return main.ERROR
4724 except TypeError:
4725 main.log.exception( self.name + ": Object not as expected" )
4726 return main.ERROR
4727 except Exception:
4728 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004729 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004730
4731 def valueTestGetAndSet( self, valueName, newValue ):
4732 """
4733 CLI command to getAndSet the value of an atomic value.
4734 Required arguments:
4735 valueName - The name of the value to get.
4736 newValue - The value to assign to the given value
4737 returns:
4738 string value of the value or
4739 None on Error
4740 """
4741 try:
4742 valueName = str( valueName )
4743 cmdStr = "value-test "
4744 operation = "getAndSet"
4745 cmdStr += valueName + " " + operation
4746 cmdStr = "value-test {} {} {}".format( valueName,
4747 operation,
4748 newValue )
4749 output = self.distPrimitivesSend( cmdStr )
4750 pattern = "(\w+)"
4751 match = re.search( pattern, output )
4752 if match:
4753 return match.group( 1 )
4754 else:
4755 main.log.error( self.name + ": valueTestGetAndSet did not" +
4756 " match expected output." )
4757 main.log.debug( self.name + " expected: " + pattern )
4758 main.log.debug( self.name + " actual: " + repr( output ) )
4759 return None
4760 except TypeError:
4761 main.log.exception( self.name + ": Object not as expected" )
4762 return None
4763 except Exception:
4764 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004765 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004766
4767 def valueTestDestroy( self, valueName ):
4768 """
4769 CLI command to destroy an atomic value.
4770 Required arguments:
4771 valueName - The name of the value to destroy.
4772 returns:
4773 main.TRUE on success or
4774 main.ERROR on Error
4775 """
4776 try:
4777 valueName = str( valueName )
4778 cmdStr = "value-test "
4779 operation = "destroy"
4780 cmdStr += valueName + " " + operation
4781 output = self.distPrimitivesSend( cmdStr )
4782 if output is not None:
4783 return main.TRUE
4784 else:
4785 return main.ERROR
4786 except TypeError:
4787 main.log.exception( self.name + ": Object not as expected" )
4788 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004789 except Exception:
4790 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004791 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004792
YPZhangfebf7302016-05-24 16:45:56 -07004793 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004794 """
4795 Description: Execute summary command in onos
4796 Returns: json object ( summary -j ), returns main.FALSE if there is
4797 no output
4798
4799 """
4800 try:
4801 cmdStr = "summary"
4802 if jsonFormat:
4803 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004804 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004805 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004806 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004807 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004808 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004809 if not handle:
4810 main.log.error( self.name + ": There is no output in " +
4811 "summary command" )
4812 return main.FALSE
4813 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004814 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004815 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004816 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004817 except TypeError:
4818 main.log.exception( self.name + ": Object not as expected" )
4819 return None
4820 except pexpect.EOF:
4821 main.log.error( self.name + ": EOF exception found" )
4822 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004823 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004824 except Exception:
4825 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004826 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004827
Jon Hall935db192016-04-19 00:22:04 -07004828 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004829 """
4830 CLI command to get the value of a key in a consistent map using
4831 transactions. This a test function and can only get keys from the
4832 test map hard coded into the cli command
4833 Required arguments:
4834 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004835 returns:
4836 The string value of the key or
4837 None on Error
4838 """
4839 try:
4840 keyName = str( keyName )
4841 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004842 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004843 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004844 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4845 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004846 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004847 return None
4848 else:
4849 match = re.search( pattern, output )
4850 if match:
4851 return match.groupdict()[ 'value' ]
4852 else:
4853 main.log.error( self.name + ": transactionlMapGet did not" +
4854 " match expected output." )
4855 main.log.debug( self.name + " expected: " + pattern )
4856 main.log.debug( self.name + " actual: " + repr( output ) )
4857 return None
4858 except TypeError:
4859 main.log.exception( self.name + ": Object not as expected" )
4860 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004861 except Exception:
4862 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004863 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004864
Jon Hall935db192016-04-19 00:22:04 -07004865 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004866 """
4867 CLI command to put a value into 'numKeys' number of keys in a
4868 consistent map using transactions. This a test function and can only
4869 put into keys named 'Key#' of the test map hard coded into the cli command
4870 Required arguments:
4871 numKeys - Number of keys to add the value to
4872 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004873 returns:
4874 A dictionary whose keys are the name of the keys put into the map
4875 and the values of the keys are dictionaries whose key-values are
4876 'value': value put into map and optionaly
4877 'oldValue': Previous value in the key or
4878 None on Error
4879
4880 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004881 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4882 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004883 """
4884 try:
4885 numKeys = str( numKeys )
4886 value = str( value )
4887 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004888 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004889 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004890 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4891 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4892 results = {}
4893 for line in output.splitlines():
4894 new = re.search( newPattern, line )
4895 updated = re.search( updatedPattern, line )
4896 if new:
4897 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4898 elif updated:
4899 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004900 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004901 else:
4902 main.log.error( self.name + ": transactionlMapGet did not" +
4903 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004904 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4905 newPattern,
4906 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004907 main.log.debug( self.name + " actual: " + repr( output ) )
4908 return results
Jon Hall0e240372018-05-02 11:21:57 -07004909 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004910 main.log.exception( self.name + ": Object not as expected" )
4911 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004912 except Exception:
4913 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004914 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004915
acsmarsdaea66c2015-09-03 11:44:06 -07004916 def maps( self, jsonFormat=True ):
4917 """
4918 Description: Returns result of onos:maps
4919 Optional:
4920 * jsonFormat: enable json formatting of output
4921 """
4922 try:
4923 cmdStr = "maps"
4924 if jsonFormat:
4925 cmdStr += " -j"
4926 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004927 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004928 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004929 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004930 except AssertionError:
4931 main.log.exception( "" )
4932 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004933 except TypeError:
4934 main.log.exception( self.name + ": Object not as expected" )
4935 return None
4936 except pexpect.EOF:
4937 main.log.error( self.name + ": EOF exception found" )
4938 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004939 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004940 except Exception:
4941 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004942 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004943
4944 def getSwController( self, uri, jsonFormat=True ):
4945 """
4946 Descrition: Gets the controller information from the device
4947 """
4948 try:
4949 cmd = "device-controllers "
4950 if jsonFormat:
4951 cmd += "-j "
4952 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004953 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004954 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004955 return response
Jon Hallc6793552016-01-19 14:18:37 -08004956 except AssertionError:
4957 main.log.exception( "" )
4958 return None
GlennRC050596c2015-11-18 17:06:41 -08004959 except TypeError:
4960 main.log.exception( self.name + ": Object not as expected" )
4961 return None
4962 except pexpect.EOF:
4963 main.log.error( self.name + ": EOF exception found" )
4964 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004965 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004966 except Exception:
4967 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004968 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004969
4970 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4971 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004972 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004973
4974 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004975 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08004976 ip - String or List: The ip address of the controller.
4977 This parameter can be formed in a couple of different ways.
4978 VALID:
4979 10.0.0.1 - just the ip address
4980 tcp:10.0.0.1 - the protocol and the ip address
4981 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4982 so that you can add controllers with different
4983 protocols and ports
4984 INVALID:
4985 10.0.0.1:6653 - this is not supported by ONOS
4986
4987 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4988 port - The port number.
4989 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4990
4991 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4992 """
4993 try:
4994 cmd = "device-setcontrollers"
4995
4996 if jsonFormat:
4997 cmd += " -j"
4998 cmd += " " + uri
4999 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005000 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08005001 for item in ip:
5002 if ":" in item:
5003 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005004 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08005005 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005006 elif "." in sitem[ 1 ]:
5007 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08005008 else:
5009 main.log.error( "Malformed entry: " + item )
5010 raise TypeError
5011 else:
5012 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08005013 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07005014 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005015 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005016 if "Error" in response:
5017 main.log.error( response )
5018 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005019 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005020 except AssertionError:
5021 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005022 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005023 except TypeError:
5024 main.log.exception( self.name + ": Object not as expected" )
5025 return main.FALSE
5026 except pexpect.EOF:
5027 main.log.error( self.name + ": EOF exception found" )
5028 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005029 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005030 except Exception:
5031 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005032 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005033
5034 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005035 '''
GlennRC20fc6522015-12-23 23:26:57 -08005036 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005037 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005038 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005039 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005040 Returns:
5041 Returns main.FALSE if an exception is thrown or an error is present
5042 in the response. Otherwise, returns main.TRUE.
5043 NOTE:
5044 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005045 '''
GlennRC20fc6522015-12-23 23:26:57 -08005046 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005047 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005048 deviceStr = device
5049 device = []
5050 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005051
5052 for d in device:
5053 time.sleep( 1 )
5054 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005055 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005056 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005057 if "Error" in response:
5058 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5059 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005060 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005061 except AssertionError:
5062 main.log.exception( "" )
5063 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005064 except TypeError:
5065 main.log.exception( self.name + ": Object not as expected" )
5066 return main.FALSE
5067 except pexpect.EOF:
5068 main.log.error( self.name + ": EOF exception found" )
5069 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005070 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005071 except Exception:
5072 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005073 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005074
5075 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005076 '''
GlennRC20fc6522015-12-23 23:26:57 -08005077 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005078 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005079 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005080 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005081 Returns:
5082 Returns main.FALSE if an exception is thrown or an error is present
5083 in the response. Otherwise, returns main.TRUE.
5084 NOTE:
5085 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005086 '''
GlennRC20fc6522015-12-23 23:26:57 -08005087 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005088 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005089 host = list( host )
5090
5091 for h in host:
5092 time.sleep( 1 )
5093 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005094 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005095 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005096 if "Error" in response:
5097 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5098 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005099 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005100 except AssertionError:
5101 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005102 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005103 except TypeError:
5104 main.log.exception( self.name + ": Object not as expected" )
5105 return main.FALSE
5106 except pexpect.EOF:
5107 main.log.error( self.name + ": EOF exception found" )
5108 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005109 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005110 except Exception:
5111 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005112 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005113
YPZhangfebf7302016-05-24 16:45:56 -07005114 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005115 '''
GlennRCed771242016-01-13 17:02:47 -08005116 Description:
5117 Bring link down or up in the null-provider.
5118 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005119 begin - (string) One end of a device or switch.
5120 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005121 returns:
5122 main.TRUE if no exceptions were thrown and no Errors are
5123 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005124 '''
GlennRCed771242016-01-13 17:02:47 -08005125 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005126 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005127 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005128 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005129 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005130 if "Error" in response or "Failure" in response:
5131 main.log.error( response )
5132 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005133 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005134 except AssertionError:
5135 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005136 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005137 except TypeError:
5138 main.log.exception( self.name + ": Object not as expected" )
5139 return main.FALSE
5140 except pexpect.EOF:
5141 main.log.error( self.name + ": EOF exception found" )
5142 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005143 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005144 except Exception:
5145 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005146 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005147
Jon Hall2c8959e2016-12-16 12:17:34 -08005148 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005149 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005150 Description:
5151 Changes the state of port in an OF switch by means of the
5152 PORTSTATUS OF messages.
5153 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005154 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5155 port - (string) target port in the device. Ex: '2'
5156 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005157 returns:
5158 main.TRUE if no exceptions were thrown and no Errors are
5159 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005160 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005161 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005162 state = state.lower()
5163 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005164 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005165 response = self.sendline( cmd, showResponse=True )
5166 assert response is not None, "Error in sendline"
5167 assert "Command not found:" not in response, response
5168 if "Error" in response or "Failure" in response:
5169 main.log.error( response )
5170 return main.FALSE
5171 return main.TRUE
5172 except AssertionError:
5173 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005174 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005175 except TypeError:
5176 main.log.exception( self.name + ": Object not as expected" )
5177 return main.FALSE
5178 except pexpect.EOF:
5179 main.log.error( self.name + ": EOF exception found" )
5180 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005181 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005182 except Exception:
5183 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005184 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005185
5186 def logSet( self, level="INFO", app="org.onosproject" ):
5187 """
5188 Set the logging level to lvl for a specific app
5189 returns main.TRUE on success
5190 returns main.FALSE if Error occurred
5191 if noExit is True, TestON will not exit, but clean up
5192 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5193 Level defaults to INFO
5194 """
5195 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005196 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -08005197 self.handle.expect( self.karafPrompt )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005198
5199 response = self.handle.before
5200 if re.search( "Error", response ):
5201 return main.FALSE
5202 return main.TRUE
5203 except pexpect.TIMEOUT:
5204 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005205 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005206 except pexpect.EOF:
5207 main.log.error( self.name + ": EOF exception found" )
5208 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005209 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005210 except Exception:
5211 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005212 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005213
5214 def getGraphDict( self, timeout=60, includeHost=False ):
5215 """
5216 Return a dictionary which describes the latest network topology data as a
5217 graph.
5218 An example of the dictionary:
5219 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5220 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5221 Each vertex should at least have an 'edges' attribute which describes the
5222 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005223 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005224 list of attributes.
5225 An example of the edges dictionary:
5226 'edges': { vertex2: { 'port': ..., 'weight': ... },
5227 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005228 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005229 in topology data.
5230 """
5231 graphDict = {}
5232 try:
5233 links = self.links()
5234 links = json.loads( links )
5235 devices = self.devices()
5236 devices = json.loads( devices )
5237 idToDevice = {}
5238 for device in devices:
5239 idToDevice[ device[ 'id' ] ] = device
5240 if includeHost:
5241 hosts = self.hosts()
5242 # FIXME: support 'includeHost' argument
5243 for link in links:
5244 nodeA = link[ 'src' ][ 'device' ]
5245 nodeB = link[ 'dst' ][ 'device' ]
5246 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005247 if nodeA not in graphDict.keys():
5248 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005249 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005250 'type': idToDevice[ nodeA ][ 'type' ],
5251 'available': idToDevice[ nodeA ][ 'available' ],
5252 'role': idToDevice[ nodeA ][ 'role' ],
5253 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5254 'hw': idToDevice[ nodeA ][ 'hw' ],
5255 'sw': idToDevice[ nodeA ][ 'sw' ],
5256 'serial': idToDevice[ nodeA ][ 'serial' ],
5257 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005258 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005259 else:
5260 # Assert nodeB is not connected to any current links of nodeA
5261 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005262 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5263 'type': link[ 'type' ],
5264 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005265 return graphDict
5266 except ( TypeError, ValueError ):
5267 main.log.exception( self.name + ": Object not as expected" )
5268 return None
5269 except KeyError:
5270 main.log.exception( self.name + ": KeyError exception found" )
5271 return None
5272 except AssertionError:
5273 main.log.exception( self.name + ": AssertionError exception found" )
5274 return None
5275 except pexpect.EOF:
5276 main.log.error( self.name + ": EOF exception found" )
5277 main.log.error( self.name + ": " + self.handle.before )
5278 return None
5279 except Exception:
5280 main.log.exception( self.name + ": Uncaught exception!" )
5281 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005282
5283 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005284 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005285 Send command to check intent-perf summary
5286 Returns: dictionary for intent-perf summary
5287 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005288 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005289 cmd = "intent-perf -s"
5290 respDic = {}
5291 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005292 assert resp is not None, "Error in sendline"
5293 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005294 try:
5295 # Generate the dictionary to return
5296 for l in resp.split( "\n" ):
5297 # Delete any white space in line
5298 temp = re.sub( r'\s+', '', l )
5299 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005300 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005301
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005302 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005303 main.log.exception( self.name + ": Object not as expected" )
5304 return None
5305 except KeyError:
5306 main.log.exception( self.name + ": KeyError exception found" )
5307 return None
5308 except AssertionError:
5309 main.log.exception( self.name + ": AssertionError exception found" )
5310 return None
5311 except pexpect.EOF:
5312 main.log.error( self.name + ": EOF exception found" )
5313 main.log.error( self.name + ": " + self.handle.before )
5314 return None
5315 except Exception:
5316 main.log.exception( self.name + ": Uncaught exception!" )
5317 return None
5318 return respDic
5319
Chiyu Chengec63bde2016-11-17 18:11:36 -08005320 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005321 """
5322 Searches the latest ONOS log file for the given search term and
5323 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005324
chengchiyu08303a02016-09-08 17:40:26 -07005325 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005326 searchTerm:
5327 The string to grep from the ONOS log.
5328 startLine:
5329 The term that decides which line is the start to search the searchTerm in
5330 the karaf log. For now, startTerm only works in 'first' mode.
5331 logNum:
5332 In some extreme cases, one karaf log is not big enough to contain all the
5333 information.Because of this, search mutiply logs is necessary to capture
5334 the right result. logNum is the number of karaf logs that we need to search
5335 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005336 mode:
5337 all: return all the strings that contain the search term
5338 last: return the last string that contains the search term
5339 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005340 num: return the number of times that the searchTerm appears in the log
5341 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005342 """
5343 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005344 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005345 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005346 logPath = '/opt/onos/log/karaf.log.'
5347 logPaths = '/opt/onos/log/karaf.log'
5348 for i in range( 1, logNum ):
5349 logPaths = logPath + str( i ) + " " + logPaths
5350 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005351 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005352 # 100000000 is just a extreme large number to make sure this function can
5353 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005354 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005355 if mode == 'all':
5356 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005357 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005358 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005359 elif mode == 'first':
5360 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5361 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005362 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005363 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005364 return num
You Wang6d301d42017-04-21 10:49:33 -07005365 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005366 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005367 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005368 else:
5369 main.log.error( self.name + " unsupported mode" )
5370 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005371 before = self.sendline( cmd )
5372 before = before.splitlines()
5373 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005374 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005375 return returnLines
5376 except AssertionError:
5377 main.log.error( self.name + " searchTerm is not string type" )
5378 return None
5379 except pexpect.EOF:
5380 main.log.error( self.name + ": EOF exception found" )
5381 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005382 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005383 except pexpect.TIMEOUT:
5384 main.log.error( self.name + ": TIMEOUT exception found" )
5385 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005386 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005387 except Exception:
5388 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005389 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005390
5391 def vplsShow( self, jsonFormat=True ):
5392 """
5393 Description: Returns result of onos:vpls show, which should list the
5394 configured VPLS networks and the assigned interfaces.
5395 Optional:
5396 * jsonFormat: enable json formatting of output
5397 Returns:
5398 The output of the command or None on error.
5399 """
5400 try:
5401 cmdStr = "vpls show"
5402 if jsonFormat:
5403 raise NotImplementedError
5404 cmdStr += " -j"
5405 handle = self.sendline( cmdStr )
5406 assert handle is not None, "Error in sendline"
5407 assert "Command not found:" not in handle, handle
5408 return handle
5409 except AssertionError:
5410 main.log.exception( "" )
5411 return None
5412 except TypeError:
5413 main.log.exception( self.name + ": Object not as expected" )
5414 return None
5415 except pexpect.EOF:
5416 main.log.error( self.name + ": EOF exception found" )
5417 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005418 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005419 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005420 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005421 return None
5422 except Exception:
5423 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005424 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005425
5426 def parseVplsShow( self ):
5427 """
5428 Parse the cli output of 'vpls show' into json output. This is required
5429 as there is currently no json output available.
5430 """
5431 try:
5432 output = []
5433 raw = self.vplsShow( jsonFormat=False )
5434 namePat = "VPLS name: (?P<name>\w+)"
5435 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5436 encapPat = "Encapsulation: (?P<encap>\w+)"
5437 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5438 mIter = re.finditer( pattern, raw )
5439 for match in mIter:
5440 item = {}
5441 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005442 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005443 if ifaces == [ "" ]:
5444 ifaces = []
5445 item[ 'interfaces' ] = ifaces
5446 encap = match.group( 'encap' )
5447 if encap != 'NONE':
5448 item[ 'encapsulation' ] = encap.lower()
5449 output.append( item )
5450 return output
5451 except Exception:
5452 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005453 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005454
5455 def vplsList( self, jsonFormat=True ):
5456 """
5457 Description: Returns result of onos:vpls list, which should list the
5458 configured VPLS networks.
5459 Optional:
5460 * jsonFormat: enable json formatting of output
5461 """
5462 try:
5463 cmdStr = "vpls list"
5464 if jsonFormat:
5465 raise NotImplementedError
5466 cmdStr += " -j"
5467 handle = self.sendline( cmdStr )
5468 assert handle is not None, "Error in sendline"
5469 assert "Command not found:" not in handle, handle
5470 return handle
5471 except AssertionError:
5472 main.log.exception( "" )
5473 return None
5474 except TypeError:
5475 main.log.exception( self.name + ": Object not as expected" )
5476 return None
5477 except pexpect.EOF:
5478 main.log.error( self.name + ": EOF exception found" )
5479 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005480 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005481 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005482 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005483 return None
5484 except Exception:
5485 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005486 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005487
5488 def vplsCreate( self, network ):
5489 """
5490 CLI command to create a new VPLS network.
5491 Required arguments:
5492 network - String name of the network to create.
5493 returns:
5494 main.TRUE on success and main.FALSE on failure
5495 """
5496 try:
5497 network = str( network )
5498 cmdStr = "vpls create "
5499 cmdStr += network
5500 output = self.sendline( cmdStr )
5501 assert output is not None, "Error in sendline"
5502 assert "Command not found:" not in output, output
5503 assert "Error executing command" not in output, output
5504 assert "VPLS already exists:" not in output, output
5505 return main.TRUE
5506 except AssertionError:
5507 main.log.exception( "" )
5508 return main.FALSE
5509 except TypeError:
5510 main.log.exception( self.name + ": Object not as expected" )
5511 return main.FALSE
5512 except pexpect.EOF:
5513 main.log.error( self.name + ": EOF exception found" )
5514 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005515 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005516 except Exception:
5517 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005518 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005519
5520 def vplsDelete( self, network ):
5521 """
5522 CLI command to delete a VPLS network.
5523 Required arguments:
5524 network - Name of the network to delete.
5525 returns:
5526 main.TRUE on success and main.FALSE on failure
5527 """
5528 try:
5529 network = str( network )
5530 cmdStr = "vpls delete "
5531 cmdStr += network
5532 output = self.sendline( cmdStr )
5533 assert output is not None, "Error in sendline"
5534 assert "Command not found:" not in output, output
5535 assert "Error executing command" not in output, output
5536 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005537 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005538 return main.TRUE
5539 except AssertionError:
5540 main.log.exception( "" )
5541 return main.FALSE
5542 except TypeError:
5543 main.log.exception( self.name + ": Object not as expected" )
5544 return main.FALSE
5545 except pexpect.EOF:
5546 main.log.error( self.name + ": EOF exception found" )
5547 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005548 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005549 except Exception:
5550 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005551 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005552
5553 def vplsAddIface( self, network, iface ):
5554 """
5555 CLI command to add an interface to a VPLS network.
5556 Required arguments:
5557 network - Name of the network to add the interface to.
5558 iface - The ONOS name for an interface.
5559 returns:
5560 main.TRUE on success and main.FALSE on failure
5561 """
5562 try:
5563 network = str( network )
5564 iface = str( iface )
5565 cmdStr = "vpls add-if "
5566 cmdStr += network + " " + iface
5567 output = self.sendline( cmdStr )
5568 assert output is not None, "Error in sendline"
5569 assert "Command not found:" not in output, output
5570 assert "Error executing command" not in output, output
5571 assert "already associated to network" not in output, output
5572 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005573 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005574 return main.TRUE
5575 except AssertionError:
5576 main.log.exception( "" )
5577 return main.FALSE
5578 except TypeError:
5579 main.log.exception( self.name + ": Object not as expected" )
5580 return main.FALSE
5581 except pexpect.EOF:
5582 main.log.error( self.name + ": EOF exception found" )
5583 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005584 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005585 except Exception:
5586 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005587 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005588
5589 def vplsRemIface( self, network, iface ):
5590 """
5591 CLI command to remove an interface from a VPLS network.
5592 Required arguments:
5593 network - Name of the network to remove the interface from.
5594 iface - Name of the interface to remove.
5595 returns:
5596 main.TRUE on success and main.FALSE on failure
5597 """
5598 try:
5599 iface = str( iface )
5600 cmdStr = "vpls rem-if "
5601 cmdStr += network + " " + iface
5602 output = self.sendline( cmdStr )
5603 assert output is not None, "Error in sendline"
5604 assert "Command not found:" not in output, output
5605 assert "Error executing command" not in output, output
5606 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005607 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005608 return main.TRUE
5609 except AssertionError:
5610 main.log.exception( "" )
5611 return main.FALSE
5612 except TypeError:
5613 main.log.exception( self.name + ": Object not as expected" )
5614 return main.FALSE
5615 except pexpect.EOF:
5616 main.log.error( self.name + ": EOF exception found" )
5617 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005618 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005619 except Exception:
5620 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005621 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005622
5623 def vplsClean( self ):
5624 """
5625 Description: Clears the VPLS app configuration.
5626 Returns: main.TRUE on success and main.FALSE on failure
5627 """
5628 try:
5629 cmdStr = "vpls clean"
5630 handle = self.sendline( cmdStr )
5631 assert handle is not None, "Error in sendline"
5632 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005633 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005634 return handle
5635 except AssertionError:
5636 main.log.exception( "" )
5637 return main.FALSE
5638 except TypeError:
5639 main.log.exception( self.name + ": Object not as expected" )
5640 return main.FALSE
5641 except pexpect.EOF:
5642 main.log.error( self.name + ": EOF exception found" )
5643 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005644 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005645 except Exception:
5646 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005647 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005648
5649 def vplsSetEncap( self, network, encapType ):
5650 """
5651 CLI command to add an interface to a VPLS network.
5652 Required arguments:
5653 network - Name of the network to create.
5654 encapType - Type of encapsulation.
5655 returns:
5656 main.TRUE on success and main.FALSE on failure
5657 """
5658 try:
5659 network = str( network )
5660 encapType = str( encapType ).upper()
5661 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5662 cmdStr = "vpls set-encap "
5663 cmdStr += network + " " + encapType
5664 output = self.sendline( cmdStr )
5665 assert output is not None, "Error in sendline"
5666 assert "Command not found:" not in output, output
5667 assert "Error executing command" not in output, output
5668 assert "already associated to network" not in output, output
5669 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005670 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005671 return main.TRUE
5672 except AssertionError:
5673 main.log.exception( "" )
5674 return main.FALSE
5675 except TypeError:
5676 main.log.exception( self.name + ": Object not as expected" )
5677 return main.FALSE
5678 except pexpect.EOF:
5679 main.log.error( self.name + ": EOF exception found" )
5680 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005681 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005682 except Exception:
5683 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005684 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005685
5686 def interfaces( self, jsonFormat=True ):
5687 """
5688 Description: Returns result of interfaces command.
5689 Optional:
5690 * jsonFormat: enable json formatting of output
5691 Returns:
5692 The output of the command or None on error.
5693 """
5694 try:
5695 cmdStr = "interfaces"
5696 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005697 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005698 cmdStr += " -j"
5699 handle = self.sendline( cmdStr )
5700 assert handle is not None, "Error in sendline"
5701 assert "Command not found:" not in handle, handle
5702 return handle
5703 except AssertionError:
5704 main.log.exception( "" )
5705 return None
5706 except TypeError:
5707 main.log.exception( self.name + ": Object not as expected" )
5708 return None
5709 except pexpect.EOF:
5710 main.log.error( self.name + ": EOF exception found" )
5711 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005712 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005713 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005714 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005715 return None
5716 except Exception:
5717 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005718 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005719
5720 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005721 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005722 Get the timestamp of searchTerm from karaf log.
5723
5724 Arguments:
5725 splitTerm_before and splitTerm_after:
5726
5727 The terms that split the string that contains the timeStamp of
5728 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5729 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5730 and the splitTerm_after is "x"
5731
5732 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005733 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005734 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005735 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005736 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005737 return main.ERROR
5738 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005739 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005740 main.log.warn( "Captured timestamp string is empty" )
5741 return main.ERROR
5742 lines = lines[ 0 ]
5743 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005744 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005745 # get the target value
5746 line = lines.split( splitTerm_before )
5747 key = line[ 1 ].split( splitTerm_after )
5748 return int( key[ 0 ] )
5749 except IndexError:
5750 main.log.warn( "Index Error!" )
5751 return main.ERROR
5752 except AssertionError:
5753 main.log.warn( "Search Term Not Found " )
5754 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005755
5756 def workQueueAdd( self, queueName, value ):
5757 """
5758 CLI command to add a string to the specified Work Queue.
5759 This function uses the distributed primitives test app, which
5760 gives some cli access to distributed primitives for testing
5761 purposes only.
5762
5763 Required arguments:
5764 queueName - The name of the queue to add to
5765 value - The value to add to the queue
5766 returns:
5767 main.TRUE on success, main.FALSE on failure and
5768 main.ERROR on error.
5769 """
5770 try:
5771 queueName = str( queueName )
5772 value = str( value )
5773 prefix = "work-queue-test"
5774 operation = "add"
5775 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5776 output = self.distPrimitivesSend( cmdStr )
5777 if "Invalid operation name" in output:
5778 main.log.warn( output )
5779 return main.ERROR
5780 elif "Done" in output:
5781 return main.TRUE
5782 except TypeError:
5783 main.log.exception( self.name + ": Object not as expected" )
5784 return main.ERROR
5785 except Exception:
5786 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005787 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005788
5789 def workQueueAddMultiple( self, queueName, value1, value2 ):
5790 """
5791 CLI command to add two strings to the specified Work Queue.
5792 This function uses the distributed primitives test app, which
5793 gives some cli access to distributed primitives for testing
5794 purposes only.
5795
5796 Required arguments:
5797 queueName - The name of the queue to add to
5798 value1 - The first value to add to the queue
5799 value2 - The second value to add to the queue
5800 returns:
5801 main.TRUE on success, main.FALSE on failure and
5802 main.ERROR on error.
5803 """
5804 try:
5805 queueName = str( queueName )
5806 value1 = str( value1 )
5807 value2 = str( value2 )
5808 prefix = "work-queue-test"
5809 operation = "addMultiple"
5810 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5811 output = self.distPrimitivesSend( cmdStr )
5812 if "Invalid operation name" in output:
5813 main.log.warn( output )
5814 return main.ERROR
5815 elif "Done" in output:
5816 return main.TRUE
5817 except TypeError:
5818 main.log.exception( self.name + ": Object not as expected" )
5819 return main.ERROR
5820 except Exception:
5821 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005822 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005823
5824 def workQueueTakeAndComplete( self, queueName, number=1 ):
5825 """
5826 CLI command to take a value from the specified Work Queue and compelte it.
5827 This function uses the distributed primitives test app, which
5828 gives some cli access to distributed primitives for testing
5829 purposes only.
5830
5831 Required arguments:
5832 queueName - The name of the queue to add to
5833 number - The number of items to take and complete
5834 returns:
5835 main.TRUE on success, main.FALSE on failure and
5836 main.ERROR on error.
5837 """
5838 try:
5839 queueName = str( queueName )
5840 number = str( int( number ) )
5841 prefix = "work-queue-test"
5842 operation = "takeAndComplete"
5843 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5844 output = self.distPrimitivesSend( cmdStr )
5845 if "Invalid operation name" in output:
5846 main.log.warn( output )
5847 return main.ERROR
5848 elif "Done" in output:
5849 return main.TRUE
5850 except TypeError:
5851 main.log.exception( self.name + ": Object not as expected" )
5852 return main.ERROR
5853 except Exception:
5854 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005855 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005856
5857 def workQueueDestroy( self, queueName ):
5858 """
5859 CLI command to destroy the specified Work Queue.
5860 This function uses the distributed primitives test app, which
5861 gives some cli access to distributed primitives for testing
5862 purposes only.
5863
5864 Required arguments:
5865 queueName - The name of the queue to add to
5866 returns:
5867 main.TRUE on success, main.FALSE on failure and
5868 main.ERROR on error.
5869 """
5870 try:
5871 queueName = str( queueName )
5872 prefix = "work-queue-test"
5873 operation = "destroy"
5874 cmdStr = " ".join( [ prefix, queueName, operation ] )
5875 output = self.distPrimitivesSend( cmdStr )
5876 if "Invalid operation name" in output:
5877 main.log.warn( output )
5878 return main.ERROR
5879 return main.TRUE
5880 except TypeError:
5881 main.log.exception( self.name + ": Object not as expected" )
5882 return main.ERROR
5883 except Exception:
5884 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005885 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005886
5887 def workQueueTotalPending( self, queueName ):
5888 """
5889 CLI command to get the Total Pending items of the specified Work Queue.
5890 This function uses the distributed primitives test app, which
5891 gives some cli access to distributed primitives for testing
5892 purposes only.
5893
5894 Required arguments:
5895 queueName - The name of the queue to add to
5896 returns:
5897 The number of Pending items in the specified work queue or
5898 None on error
5899 """
5900 try:
5901 queueName = str( queueName )
5902 prefix = "work-queue-test"
5903 operation = "totalPending"
5904 cmdStr = " ".join( [ prefix, queueName, operation ] )
5905 output = self.distPrimitivesSend( cmdStr )
5906 pattern = r'\d+'
5907 if "Invalid operation name" in output:
5908 main.log.warn( output )
5909 return None
5910 else:
5911 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005912 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005913 except ( AttributeError, TypeError ):
5914 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5915 return None
5916 except Exception:
5917 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005918 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005919
5920 def workQueueTotalCompleted( self, queueName ):
5921 """
5922 CLI command to get the Total Completed items of the specified Work Queue.
5923 This function uses the distributed primitives test app, which
5924 gives some cli access to distributed primitives for testing
5925 purposes only.
5926
5927 Required arguments:
5928 queueName - The name of the queue to add to
5929 returns:
5930 The number of complete items in the specified work queue or
5931 None on error
5932 """
5933 try:
5934 queueName = str( queueName )
5935 prefix = "work-queue-test"
5936 operation = "totalCompleted"
5937 cmdStr = " ".join( [ prefix, queueName, operation ] )
5938 output = self.distPrimitivesSend( cmdStr )
5939 pattern = r'\d+'
5940 if "Invalid operation name" in output:
5941 main.log.warn( output )
5942 return None
5943 else:
5944 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005945 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005946 except ( AttributeError, TypeError ):
5947 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5948 return None
5949 except Exception:
5950 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005951 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005952
5953 def workQueueTotalInProgress( self, queueName ):
5954 """
5955 CLI command to get the Total In Progress items of the specified Work Queue.
5956 This function uses the distributed primitives test app, which
5957 gives some cli access to distributed primitives for testing
5958 purposes only.
5959
5960 Required arguments:
5961 queueName - The name of the queue to add to
5962 returns:
5963 The number of In Progress items in the specified work queue or
5964 None on error
5965 """
5966 try:
5967 queueName = str( queueName )
5968 prefix = "work-queue-test"
5969 operation = "totalInProgress"
5970 cmdStr = " ".join( [ prefix, queueName, operation ] )
5971 output = self.distPrimitivesSend( cmdStr )
5972 pattern = r'\d+'
5973 if "Invalid operation name" in output:
5974 main.log.warn( output )
5975 return None
5976 else:
5977 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005978 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005979 except ( AttributeError, TypeError ):
5980 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5981 return None
5982 except Exception:
5983 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005984 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005985
5986 def events( self, args='-a' ):
5987 """
5988 Description: Returns events -a command output
5989 Optional:
5990 add other arguments
5991 """
5992 try:
5993 cmdStr = "events"
5994 if args:
5995 cmdStr += " " + args
5996 handle = self.sendline( cmdStr )
5997 assert handle is not None, "Error in sendline"
5998 assert "Command not found:" not in handle, handle
5999 return handle
6000 except AssertionError:
6001 main.log.exception( "" )
6002 return None
6003 except TypeError:
6004 main.log.exception( self.name + ": Object not as expected" )
6005 return None
6006 except pexpect.EOF:
6007 main.log.error( self.name + ": EOF exception found" )
6008 main.log.error( self.name + ": " + self.handle.before )
6009 main.cleanAndExit()
6010 except Exception:
6011 main.log.exception( self.name + ": Uncaught exception!" )
6012 main.cleanAndExit()
6013
6014 def getMaster( self, deviceID ):
6015 """
6016 Description: Obtains current master using "roles" command for a specific deviceID
6017 """
6018 try:
6019 return str( self.getRole( deviceID )[ 'master' ] )
6020 except AssertionError:
6021 main.log.exception( "" )
6022 return None
6023 except TypeError:
6024 main.log.exception( self.name + ": Object not as expected" )
6025 return None
6026 except pexpect.EOF:
6027 main.log.error( self.name + ": EOF exception found" )
6028 main.log.error( self.name + ": " + self.handle.before )
6029 main.cleanAndExit()
6030 except Exception:
6031 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006032 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006033
6034 def issu( self ):
6035 """
6036 Short summary of In-Service Software Upgrade status
6037
6038 Returns the output of the cli command or None on Error
6039 """
6040 try:
6041 cmdStr = "issu"
6042 handle = self.sendline( cmdStr )
6043 assert handle is not None, "Error in sendline"
6044 assert "Command not found:" not in handle, handle
6045 assert "Unsupported command:" not in handle, handle
6046 return handle
6047 except AssertionError:
6048 main.log.exception( "" )
6049 return None
6050 except TypeError:
6051 main.log.exception( self.name + ": Object not as expected" )
6052 return None
6053 except pexpect.EOF:
6054 main.log.error( self.name + ": EOF exception found" )
6055 main.log.error( self.name + ": " + self.handle.before )
6056 main.cleanAndExit()
6057 except Exception:
6058 main.log.exception( self.name + ": Uncaught exception!" )
6059 main.cleanAndExit()
6060
6061 def issuInit( self ):
6062 """
6063 Initiates an In-Service Software Upgrade
6064
6065 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6066 """
6067 try:
6068 cmdStr = "issu init"
6069 handle = self.sendline( cmdStr )
6070 assert handle is not None, "Error in sendline"
6071 assert "Command not found:" not in handle, handle
6072 assert "Unsupported command:" not in handle, handle
6073 if "Initialized" in handle:
6074 return main.TRUE
6075 else:
6076 return main.FALSE
6077 except AssertionError:
6078 main.log.exception( "" )
6079 return main.ERROR
6080 except TypeError:
6081 main.log.exception( self.name + ": Object not as expected" )
6082 return main.ERROR
6083 except pexpect.EOF:
6084 main.log.error( self.name + ": EOF exception found" )
6085 main.log.error( self.name + ": " + self.handle.before )
6086 main.cleanAndExit()
6087 except Exception:
6088 main.log.exception( self.name + ": Uncaught exception!" )
6089 main.cleanAndExit()
6090
6091 def issuUpgrade( self ):
6092 """
6093 Transitions stores to upgraded nodes
6094
6095 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6096 """
6097 try:
6098 cmdStr = "issu upgrade"
6099 handle = self.sendline( cmdStr )
6100 assert handle is not None, "Error in sendline"
6101 assert "Command not found:" not in handle, handle
6102 assert "Unsupported command:" not in handle, handle
6103 if "Upgraded" in handle:
6104 return main.TRUE
6105 else:
6106 return main.FALSE
6107 except AssertionError:
6108 main.log.exception( "" )
6109 return main.ERROR
6110 except TypeError:
6111 main.log.exception( self.name + ": Object not as expected" )
6112 return main.ERROR
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()
6120
6121 def issuCommit( self ):
6122 """
6123 Finalizes an In-Service Software Upgrade
6124
6125 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6126 """
6127 try:
6128 cmdStr = "issu commit"
6129 handle = self.sendline( cmdStr )
6130 assert handle is not None, "Error in sendline"
6131 assert "Command not found:" not in handle, handle
6132 assert "Unsupported command:" not in handle, handle
6133 # TODO: Check the version returned by this command
6134 if "Committed version" in handle:
6135 return main.TRUE
6136 else:
6137 return main.FALSE
6138 except AssertionError:
6139 main.log.exception( "" )
6140 return main.ERROR
6141 except TypeError:
6142 main.log.exception( self.name + ": Object not as expected" )
6143 return main.ERROR
6144 except pexpect.EOF:
6145 main.log.error( self.name + ": EOF exception found" )
6146 main.log.error( self.name + ": " + self.handle.before )
6147 main.cleanAndExit()
6148 except Exception:
6149 main.log.exception( self.name + ": Uncaught exception!" )
6150 main.cleanAndExit()
6151
6152 def issuRollback( self ):
6153 """
6154 Rolls back an In-Service Software Upgrade
6155
6156 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6157 """
6158 try:
6159 cmdStr = "issu rollback"
6160 handle = self.sendline( cmdStr )
6161 assert handle is not None, "Error in sendline"
6162 assert "Command not found:" not in handle, handle
6163 assert "Unsupported command:" not in handle, handle
6164 # TODO: Check the version returned by this command
6165 if "Rolled back to version" in handle:
6166 return main.TRUE
6167 else:
6168 return main.FALSE
6169 except AssertionError:
6170 main.log.exception( "" )
6171 return main.ERROR
6172 except TypeError:
6173 main.log.exception( self.name + ": Object not as expected" )
6174 return main.ERROR
6175 except pexpect.EOF:
6176 main.log.error( self.name + ": EOF exception found" )
6177 main.log.error( self.name + ": " + self.handle.before )
6178 main.cleanAndExit()
6179 except Exception:
6180 main.log.exception( self.name + ": Uncaught exception!" )
6181 main.cleanAndExit()
6182
6183 def issuReset( self ):
6184 """
6185 Resets the In-Service Software Upgrade status after a rollback
6186
6187 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6188 """
6189 try:
6190 cmdStr = "issu reset"
6191 handle = self.sendline( cmdStr )
6192 assert handle is not None, "Error in sendline"
6193 assert "Command not found:" not in handle, handle
6194 assert "Unsupported command:" not in handle, handle
6195 # TODO: Check the version returned by this command
6196 if "Reset version" in handle:
6197 return main.TRUE
6198 else:
6199 return main.FALSE
6200 except AssertionError:
6201 main.log.exception( "" )
6202 return main.ERROR
6203 except TypeError:
6204 main.log.exception( self.name + ": Object not as expected" )
6205 return main.ERROR
6206 except pexpect.EOF:
6207 main.log.error( self.name + ": EOF exception found" )
6208 main.log.error( self.name + ": " + self.handle.before )
6209 main.cleanAndExit()
6210 except Exception:
6211 main.log.exception( self.name + ": Uncaught exception!" )
6212 main.cleanAndExit()
6213
6214 def issuStatus( self ):
6215 """
6216 Status of an In-Service Software Upgrade
6217
6218 Returns the output of the cli command or None on Error
6219 """
6220 try:
6221 cmdStr = "issu status"
6222 handle = self.sendline( cmdStr )
6223 assert handle is not None, "Error in sendline"
6224 assert "Command not found:" not in handle, handle
6225 assert "Unsupported command:" not in handle, handle
6226 return handle
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 issuVersion( self ):
6242 """
6243 Get the version of an In-Service Software Upgrade
6244
6245 Returns the output of the cli command or None on Error
6246 """
6247 try:
6248 cmdStr = "issu version"
6249 handle = self.sendline( cmdStr )
6250 assert handle is not None, "Error in sendline"
6251 assert "Command not found:" not in handle, handle
6252 assert "Unsupported command:" not in handle, handle
6253 return handle
6254 except AssertionError:
6255 main.log.exception( "" )
6256 return None
6257 except TypeError:
6258 main.log.exception( self.name + ": Object not as expected" )
6259 return None
6260 except pexpect.EOF:
6261 main.log.error( self.name + ": EOF exception found" )
6262 main.log.error( self.name + ": " + self.handle.before )
6263 main.cleanAndExit()
6264 except Exception:
6265 main.log.exception( self.name + ": Uncaught exception!" )
6266 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006267
6268 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6269 """
6270 Create a multicast route by calling 'mcast-join' command
6271 sIP: source IP of the multicast route
6272 groupIP: group IP of the multicast route
6273 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6274 dPorts: a list of destination ports of the multicast route
6275 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6276 """
6277 try:
6278 cmdStr = "mcast-join"
6279 cmdStr += " " + str( sIP )
6280 cmdStr += " " + str( groupIP )
6281 cmdStr += " " + str( sPort )
6282 assert isinstance( dPorts, list )
6283 for dPort in dPorts:
6284 cmdStr += " " + str( dPort )
6285 handle = self.sendline( cmdStr )
6286 assert handle is not None, "Error in sendline"
6287 assert "Command not found:" not in handle, handle
6288 assert "Unsupported command:" not in handle, handle
6289 assert "Error executing command" not in handle, handle
6290 if "Added the mcast route" in handle:
6291 return main.TRUE
6292 else:
6293 return main.FALSE
6294 except AssertionError:
6295 main.log.exception( "" )
6296 return None
6297 except TypeError:
6298 main.log.exception( self.name + ": Object not as expected" )
6299 return None
6300 except pexpect.EOF:
6301 main.log.error( self.name + ": EOF exception found" )
6302 main.log.error( self.name + ": " + self.handle.before )
6303 main.cleanAndExit()
6304 except Exception:
6305 main.log.exception( self.name + ": Uncaught exception!" )
6306 main.cleanAndExit()
6307
6308 def mcastDelete( self, sIP, groupIP, dPorts ):
6309 """
6310 Delete a multicast route by calling 'mcast-delete' command
6311 sIP: source IP of the multicast route
6312 groupIP: group IP of the multicast route
6313 dPorts: a list of destination ports of the multicast route
6314 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6315 """
6316 try:
6317 cmdStr = "mcast-delete"
6318 cmdStr += " " + str( sIP )
6319 cmdStr += " " + str( groupIP )
6320 assert isinstance( dPorts, list )
6321 for dPort in dPorts:
6322 cmdStr += " " + str( dPort )
6323 handle = self.sendline( cmdStr )
6324 assert handle is not None, "Error in sendline"
6325 assert "Command not found:" not in handle, handle
6326 assert "Unsupported command:" not in handle, handle
6327 assert "Error executing command" not in handle, handle
6328 if "Updated the mcast route" in handle:
6329 return main.TRUE
6330 else:
6331 return main.FALSE
6332 except AssertionError:
6333 main.log.exception( "" )
6334 return None
6335 except TypeError:
6336 main.log.exception( self.name + ": Object not as expected" )
6337 return None
6338 except pexpect.EOF:
6339 main.log.error( self.name + ": EOF exception found" )
6340 main.log.error( self.name + ": " + self.handle.before )
6341 main.cleanAndExit()
6342 except Exception:
6343 main.log.exception( self.name + ": Uncaught exception!" )
6344 main.cleanAndExit()
6345
6346 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6347 """
6348 Create a multicast route by calling 'mcast-host-join' command
6349 sAddr: we can provide * for ASM or a specific address for SSM
6350 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006351 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006352 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6353 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6354 """
6355 try:
6356 cmdStr = "mcast-host-join"
6357 cmdStr += " -sAddr " + str( sAddr )
6358 cmdStr += " -gAddr " + str( gAddr )
6359 assert isinstance( srcs, list )
6360 for src in srcs:
6361 cmdStr += " -srcs " + str( src )
6362 assert isinstance( sinks, list )
6363 for sink in sinks:
6364 cmdStr += " -sinks " + str( sink )
6365 handle = self.sendline( cmdStr )
6366 assert handle is not None, "Error in sendline"
6367 assert "Command not found:" not in handle, handle
6368 assert "Unsupported command:" not in handle, handle
6369 assert "Error executing command" not in handle, handle
6370 if "Added the mcast route" in handle:
6371 return main.TRUE
6372 else:
6373 return main.FALSE
6374 except AssertionError:
6375 main.log.exception( "" )
6376 return None
6377 except TypeError:
6378 main.log.exception( self.name + ": Object not as expected" )
6379 return None
6380 except pexpect.EOF:
6381 main.log.error( self.name + ": EOF exception found" )
6382 main.log.error( self.name + ": " + self.handle.before )
6383 main.cleanAndExit()
6384 except Exception:
6385 main.log.exception( self.name + ": Uncaught exception!" )
6386 main.cleanAndExit()
6387
6388 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6389 """
6390 Delete multicast sink(s) by calling 'mcast-host-delete' command
6391 sAddr: we can provide * for ASM or a specific address for SSM
6392 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006393 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006394 will delete the route if not specified
6395 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6396 """
6397 try:
6398 cmdStr = "mcast-host-delete"
6399 cmdStr += " -sAddr " + str( sAddr )
6400 cmdStr += " -gAddr " + str( gAddr )
6401 if host:
6402 cmdStr += " -h " + str( host )
6403 handle = self.sendline( cmdStr )
6404 assert handle is not None, "Error in sendline"
6405 assert "Command not found:" not in handle, handle
6406 assert "Unsupported command:" not in handle, handle
6407 assert "Error executing command" not in handle, handle
6408 if "Updated the mcast route" in handle:
6409 return main.TRUE
6410 elif "Deleted the mcast route" in handle:
6411 return main.TRUE
6412 else:
6413 return main.FALSE
6414 except AssertionError:
6415 main.log.exception( "" )
6416 return None
6417 except TypeError:
6418 main.log.exception( self.name + ": Object not as expected" )
6419 return None
6420 except pexpect.EOF:
6421 main.log.error( self.name + ": EOF exception found" )
6422 main.log.error( self.name + ": " + self.handle.before )
6423 main.cleanAndExit()
6424 except Exception:
6425 main.log.exception( self.name + ": Uncaught exception!" )
6426 main.cleanAndExit()
6427
You Wang547893e2018-05-08 13:34:59 -07006428 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6429 """
6430 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6431 sAddr: we can provide * for ASM or a specific address for SSM
6432 gAddr: specifies multicast group address
6433 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6434 will delete the route if not specified
6435 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6436 """
6437 try:
6438 cmdStr = "mcast-sink-delete"
6439 cmdStr += " -sAddr " + str( sAddr )
6440 cmdStr += " -gAddr " + str( gAddr )
6441 if sink:
6442 cmdStr += " -s " + str( sink )
6443 handle = self.sendline( cmdStr )
6444 assert handle is not None, "Error in sendline"
6445 assert "Command not found:" not in handle, handle
6446 assert "Unsupported command:" not in handle, handle
6447 assert "Error executing command" not in handle, handle
6448 if "Updated the mcast route" in handle:
6449 return main.TRUE
6450 elif "Deleted the mcast route" in handle:
6451 return main.TRUE
6452 else:
6453 return main.FALSE
6454 except AssertionError:
6455 main.log.exception( "" )
6456 return None
6457 except TypeError:
6458 main.log.exception( self.name + ": Object not as expected" )
6459 return None
6460 except pexpect.EOF:
6461 main.log.error( self.name + ": EOF exception found" )
6462 main.log.error( self.name + ": " + self.handle.before )
6463 main.cleanAndExit()
6464 except Exception:
6465 main.log.exception( self.name + ": Uncaught exception!" )
6466 main.cleanAndExit()
6467
You Wange24d6272018-03-27 21:18:50 -07006468 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6469 """
6470 Delete multicast src(s) by calling 'mcast-source-delete' command
6471 sAddr: we can provide * for ASM or a specific address for SSM
6472 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006473 srcs: a list of host IDs of the sources e.g. ["00:AA:00:00:01:05/40"],
You Wange24d6272018-03-27 21:18:50 -07006474 will delete the route if not specified
6475 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6476 """
6477 try:
6478 cmdStr = "mcast-source-delete"
6479 cmdStr += " -sAddr " + str( sAddr )
6480 cmdStr += " -gAddr " + str( gAddr )
6481 if srcs:
6482 assert isinstance( srcs, list )
6483 for src in srcs:
6484 cmdStr += " -src " + str( src )
6485 handle = self.sendline( cmdStr )
6486 assert handle is not None, "Error in sendline"
6487 assert "Command not found:" not in handle, handle
6488 assert "Unsupported command:" not in handle, handle
6489 assert "Error executing command" not in handle, handle
6490 if "Updated the mcast route" in handle:
6491 return main.TRUE
6492 elif "Deleted the mcast route" in handle:
6493 return main.TRUE
6494 else:
6495 return main.FALSE
6496 except AssertionError:
6497 main.log.exception( "" )
6498 return None
6499 except TypeError:
6500 main.log.exception( self.name + ": Object not as expected" )
6501 return None
6502 except pexpect.EOF:
6503 main.log.error( self.name + ": EOF exception found" )
6504 main.log.error( self.name + ": " + self.handle.before )
6505 main.cleanAndExit()
6506 except Exception:
6507 main.log.exception( self.name + ": Uncaught exception!" )
6508 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006509
6510 def netcfg( self, jsonFormat=True, args="" ):
6511 """
6512 Run netcfg cli command with given args
6513 """
6514 try:
6515 cmdStr = "netcfg"
6516 if jsonFormat:
6517 cmdStr = cmdStr + " -j"
6518 if args:
6519 cmdStr = cmdStr + " " + str( args )
6520 handle = self.sendline( cmdStr )
6521 assert handle is not None, "Error in sendline"
6522 assert "Command not found:" not in handle, handle
6523 assert "Unsupported command:" not in handle, handle
6524 assert "Error executing command" not in handle, handle
6525 return handle
6526 except AssertionError:
6527 main.log.exception( "" )
6528 return None
6529 except TypeError:
6530 main.log.exception( self.name + ": Object not as expected" )
6531 return None
6532 except pexpect.EOF:
6533 main.log.error( self.name + ": EOF exception found" )
6534 main.log.error( self.name + ": " + self.handle.before )
6535 main.cleanAndExit()
6536 except Exception:
6537 main.log.exception( self.name + ": Uncaught exception!" )
6538 main.cleanAndExit()
6539
You Wang0fa76e72018-05-18 11:33:25 -07006540 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006541 """
You Wang54b1d672018-06-11 16:44:13 -07006542 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006543 Options:
6544 sAddr: IP address of the source host
6545 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006546 ipv6: True if hosts are IPv6
6547 verbose: return verbose t3 output if True
6548 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006549 """
6550 try:
6551 # Collect information of both hosts from onos
6552 hosts = self.hosts()
6553 hosts = json.loads( hosts )
6554 sHost = None
6555 dHost = None
6556 for host in hosts:
6557 if sAddr in host[ "ipAddresses" ]:
6558 sHost = host
6559 elif dAddr in host[ "ipAddresses" ]:
6560 dHost = host
6561 if sHost and dHost:
6562 break
6563 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006564 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006565 if simple:
6566 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006567 cmdStr = "t3-troubleshoot-simple"
6568 if verbose:
6569 cmdStr += " -vv"
6570 if ipv6:
6571 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006572 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006573 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006574 else:
You Wang54b1d672018-06-11 16:44:13 -07006575 for location in sHost[ "locations" ]:
6576 cmdStr = "t3-troubleshoot"
6577 if verbose:
6578 cmdStr += " -vv"
6579 if ipv6:
6580 cmdStr += " -et ipv6"
6581 cmdStr += " -s " + str( sAddr )
6582 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6583 cmdStr += " -sm " + str( sHost[ "mac" ] )
6584 if sHost[ "vlan" ] != "None":
6585 cmdStr += " -vid " + sHost[ "vlan" ]
6586 cmdStr += " -d " + str( dAddr )
6587 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6588 netcfg = json.loads( netcfg )
6589 assert netcfg, "Failed to get netcfg"
6590 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6591 cmdList.append( cmdStr )
6592 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006593 except AssertionError:
6594 main.log.exception( "" )
6595 return None
6596 except ( KeyError, TypeError ):
6597 main.log.exception( self.name + ": Object not as expected" )
6598 return None
6599 except Exception:
6600 main.log.exception( self.name + ": Uncaught exception!" )
6601 main.cleanAndExit()
6602
6603 def t3( self, sAddr, dAddr, ipv6=False ):
6604 """
You Wang54b1d672018-06-11 16:44:13 -07006605 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006606 Options:
6607 sAddr: IP address of the source host
6608 dAddr: IP address of the destination host
6609 """
6610 try:
You Wang54b1d672018-06-11 16:44:13 -07006611 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6612 assert cmdList is not None, "composeT3Command returned None"
6613 t3Output = ""
6614 for cmdStr in cmdList:
6615 handle = self.sendline( cmdStr )
6616 assert handle is not None, "Error in sendline"
6617 assert "Command not found:" not in handle, handle
6618 assert "Unsupported command:" not in handle, handle
6619 assert "Error executing command" not in handle, handle
6620 assert "Tracing packet" in handle
6621 t3Output += handle
6622 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006623 except AssertionError:
6624 main.log.exception( "" )
6625 return None
6626 except pexpect.EOF:
6627 main.log.error( self.name + ": EOF exception found" )
6628 main.log.error( self.name + ": " + self.handle.before )
6629 main.cleanAndExit()
6630 except Exception:
6631 main.log.exception( self.name + ": Uncaught exception!" )
6632 main.cleanAndExit()