blob: 626e8ca70ccc81ec2416a2e46e88621c73ea2ec8 [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 Hall0623dd42018-11-13 14:32:23 -0800601 if len(output) < 2:
602 output = response.split( endStr.strip()[-5:], 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700603 if output:
604 if debug:
605 main.log.debug( self.name + ": split output" )
606 for r in output:
607 main.log.debug( self.name + ": " + repr( r ) )
608 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800609 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800610 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700611 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800612 return output
GlennRCed771242016-01-13 17:02:47 -0800613 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700614 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800615 if debug:
616 main.log.debug( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700617 self.handle.send( "\x03" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800618 self.handle.expect( self.karafPrompt )
GlennRCed771242016-01-13 17:02:47 -0800619 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700620 except IndexError:
621 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700622 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700623 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800624 except TypeError:
625 main.log.exception( self.name + ": Object not as expected" )
626 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400627 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800628 main.log.error( self.name + ": EOF exception found" )
629 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700630 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700631 return None
632 else:
Devin Lim44075962017-08-11 10:56:37 -0700633 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800634 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800635 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700636 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700637 return None
638 else:
Devin Lim44075962017-08-11 10:56:37 -0700639 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400640
kelvin8ec71442015-01-15 16:57:00 -0800641 # IMPORTANT NOTE:
642 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800643 # the cli command changing 'a:b' with 'aB'.
644 # Ex ) onos:topology > onosTopology
645 # onos:links > onosLinks
646 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800647
kelvin-onlabd3b64892015-01-20 13:26:24 -0800648 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800649 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400650 Adds a new cluster node by ID and address information.
651 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800652 * nodeId
653 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400654 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800655 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800656 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400657 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800658 cmdStr = "add-node " + str( nodeId ) + " " +\
659 str( ONOSIp ) + " " + str( tcpPort )
660 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700661 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800662 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800663 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700664 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800665 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800666 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400667 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800668 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400669 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800670 except AssertionError:
671 main.log.exception( "" )
672 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800673 except TypeError:
674 main.log.exception( self.name + ": Object not as expected" )
675 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400676 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800677 main.log.error( self.name + ": EOF exception found" )
678 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700679 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800680 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800681 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700682 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400683
kelvin-onlabd3b64892015-01-20 13:26:24 -0800684 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800685 """
andrewonlab86dc3082014-10-13 18:18:38 -0400686 Removes a cluster by ID
687 Issues command: 'remove-node [<node-id>]'
688 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800690 """
andrewonlab86dc3082014-10-13 18:18:38 -0400691 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400692
kelvin-onlabd3b64892015-01-20 13:26:24 -0800693 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700694 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700695 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800696 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700697 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700698 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700699 main.log.error( handle )
700 return main.FALSE
701 else:
702 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800703 except AssertionError:
704 main.log.exception( "" )
705 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800706 except TypeError:
707 main.log.exception( self.name + ": Object not as expected" )
708 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400709 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800710 main.log.error( self.name + ": EOF exception found" )
711 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700712 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800713 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800714 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700715 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400716
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700717 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800718 """
andrewonlab7c211572014-10-15 16:45:20 -0400719 List the nodes currently visible
720 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700721 Optional argument:
722 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800723 """
andrewonlab7c211572014-10-15 16:45:20 -0400724 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700725 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700726 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700727 cmdStr += " -j"
728 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700729 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800730 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700731 return output
Jon Hallc6793552016-01-19 14:18:37 -0800732 except AssertionError:
733 main.log.exception( "" )
734 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800735 except TypeError:
736 main.log.exception( self.name + ": Object not as expected" )
737 return None
andrewonlab7c211572014-10-15 16:45:20 -0400738 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800739 main.log.error( self.name + ": EOF exception found" )
740 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700741 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800742 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800743 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700744 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400745
kelvin8ec71442015-01-15 16:57:00 -0800746 def topology( self ):
747 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700748 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700749 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700750 Return:
751 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800752 """
andrewonlab95ce8322014-10-13 14:12:04 -0400753 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700754 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800755 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800756 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800757 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700758 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400759 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800760 except AssertionError:
761 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800762 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800763 except TypeError:
764 main.log.exception( self.name + ": Object not as expected" )
765 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400766 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800767 main.log.error( self.name + ": EOF exception found" )
768 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700769 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800770 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800771 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700772 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800773
jenkins7ead5a82015-03-13 10:28:21 -0700774 def deviceRemove( self, deviceId ):
775 """
776 Removes particular device from storage
777
778 TODO: refactor this function
779 """
780 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700781 cmdStr = "device-remove " + str( deviceId )
782 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800783 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800784 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700785 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700786 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700787 main.log.error( handle )
788 return main.FALSE
789 else:
790 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800791 except AssertionError:
792 main.log.exception( "" )
793 return None
jenkins7ead5a82015-03-13 10:28:21 -0700794 except TypeError:
795 main.log.exception( self.name + ": Object not as expected" )
796 return None
797 except pexpect.EOF:
798 main.log.error( self.name + ": EOF exception found" )
799 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700800 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700801 except Exception:
802 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700803 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700804
You Wang3b9689a2018-08-30 12:24:00 -0700805 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800806 """
Jon Hall7b02d952014-10-17 20:14:54 -0400807 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400808 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800809 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800810 """
andrewonlab86dc3082014-10-13 18:18:38 -0400811 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700812 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800813 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700814 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700815 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800816 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800817 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700818 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800819 except AssertionError:
820 main.log.exception( "" )
821 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800822 except TypeError:
823 main.log.exception( self.name + ": Object not as expected" )
824 return None
andrewonlab7c211572014-10-15 16:45:20 -0400825 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800826 main.log.error( self.name + ": EOF exception found" )
827 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700828 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800829 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800830 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700831 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400832
kelvin-onlabd3b64892015-01-20 13:26:24 -0800833 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800834 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800835 This balances the devices across all controllers
836 by issuing command: 'onos> onos:balance-masters'
837 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800838 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800839 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800840 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700841 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800842 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800843 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700844 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700845 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700846 main.log.error( handle )
847 return main.FALSE
848 else:
849 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800850 except AssertionError:
851 main.log.exception( "" )
852 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800853 except TypeError:
854 main.log.exception( self.name + ": Object not as expected" )
855 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800856 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800857 main.log.error( self.name + ": EOF exception found" )
858 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700859 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800860 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800861 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700862 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800863
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000864 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700865 """
866 Returns the output of the masters command.
867 Optional argument:
868 * jsonFormat - boolean indicating if you want output in json
869 """
870 try:
871 cmdStr = "onos:masters"
872 if jsonFormat:
873 cmdStr += " -j"
874 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700875 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800876 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700877 return output
Jon Hallc6793552016-01-19 14:18:37 -0800878 except AssertionError:
879 main.log.exception( "" )
880 return None
acsmars24950022015-07-30 18:00:43 -0700881 except TypeError:
882 main.log.exception( self.name + ": Object not as expected" )
883 return None
884 except pexpect.EOF:
885 main.log.error( self.name + ": EOF exception found" )
886 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700887 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700888 except Exception:
889 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700890 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700891
Jon Hallc6793552016-01-19 14:18:37 -0800892 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700893 """
894 Uses the master command to check that the devices' leadership
895 is evenly divided
896
897 Dependencies: checkMasters() and summary()
898
Jon Hall6509dbf2016-06-21 17:01:17 -0700899 Returns main.TRUE if the devices are balanced
900 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700901 Exits on Exception
902 Returns None on TypeError
903 """
904 try:
Jon Hallc6793552016-01-19 14:18:37 -0800905 summaryOutput = self.summary()
906 totalDevices = json.loads( summaryOutput )[ "devices" ]
907 except ( TypeError, ValueError ):
908 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
909 return None
910 try:
acsmars24950022015-07-30 18:00:43 -0700911 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800912 mastersOutput = self.checkMasters()
913 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700914 first = masters[ 0 ][ "size" ]
915 for master in masters:
916 totalOwnedDevices += master[ "size" ]
917 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
918 main.log.error( "Mastership not balanced" )
919 main.log.info( "\n" + self.checkMasters( False ) )
920 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700921 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700922 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700923 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800924 except ( TypeError, ValueError ):
925 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700926 return None
927 except pexpect.EOF:
928 main.log.error( self.name + ": EOF exception found" )
929 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700930 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700931 except Exception:
932 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700933 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700934
YPZhangfebf7302016-05-24 16:45:56 -0700935 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800936 """
Jon Halle8217482014-10-17 13:49:14 -0400937 Lists all core links
938 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800939 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800940 """
Jon Halle8217482014-10-17 13:49:14 -0400941 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700942 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800943 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700944 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700945 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800946 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800947 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700948 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800949 except AssertionError:
950 main.log.exception( "" )
951 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800952 except TypeError:
953 main.log.exception( self.name + ": Object not as expected" )
954 return None
Jon Halle8217482014-10-17 13:49:14 -0400955 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800956 main.log.error( self.name + ": EOF exception found" )
957 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700958 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800959 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800960 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700961 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400962
You Wang3b9689a2018-08-30 12:24:00 -0700963 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800964 """
Jon Halle8217482014-10-17 13:49:14 -0400965 Lists all ports
966 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800967 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800968 """
Jon Halle8217482014-10-17 13:49:14 -0400969 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700970 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700972 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700973 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800974 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800975 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700976 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800977 except AssertionError:
978 main.log.exception( "" )
979 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800980 except TypeError:
981 main.log.exception( self.name + ": Object not as expected" )
982 return None
Jon Halle8217482014-10-17 13:49:14 -0400983 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800984 main.log.error( self.name + ": EOF exception found" )
985 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700986 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800987 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800988 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700989 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400990
kelvin-onlabd3b64892015-01-20 13:26:24 -0800991 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800992 """
Jon Hall983a1702014-10-28 18:44:22 -0400993 Lists all devices and the controllers with roles assigned to them
994 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800995 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800996 """
andrewonlab7c211572014-10-15 16:45:20 -0400997 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700998 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800999 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001000 cmdStr += " -j"
1001 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001002 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001003 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001004 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001005 except AssertionError:
1006 main.log.exception( "" )
1007 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001008 except TypeError:
1009 main.log.exception( self.name + ": Object not as expected" )
1010 return None
Jon Hall983a1702014-10-28 18:44:22 -04001011 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001012 main.log.error( self.name + ": EOF exception found" )
1013 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001014 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001015 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001016 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001017 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -04001018
kelvin-onlabd3b64892015-01-20 13:26:24 -08001019 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001020 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001021 Given the a string containing the json representation of the "roles"
1022 cli command and a partial or whole device id, returns a json object
1023 containing the roles output for the first device whose id contains
1024 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001025
1026 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001027 A dict of the role assignments for the given device or
1028 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001029 """
Jon Hall983a1702014-10-28 18:44:22 -04001030 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001031 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001032 return None
1033 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001034 rawRoles = self.roles()
1035 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001036 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001037 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001038 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001039 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001040 return device
1041 return None
Jon Hallc6793552016-01-19 14:18:37 -08001042 except ( TypeError, ValueError ):
1043 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001044 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001045 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001046 main.log.error( self.name + ": EOF exception found" )
1047 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001048 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001049 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001050 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001051 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001052
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001054 """
Jon Hall94fd0472014-12-08 11:52:42 -08001055 Iterates through each device and checks if there is a master assigned
1056 Returns: main.TRUE if each device has a master
1057 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001058 """
Jon Hall94fd0472014-12-08 11:52:42 -08001059 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001060 rawRoles = self.roles()
1061 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001062 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001063 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001064 # print device
1065 if device[ 'master' ] == "none":
1066 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001067 return main.FALSE
1068 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001069 except ( TypeError, ValueError ):
1070 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001071 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001072 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001073 main.log.error( self.name + ": EOF exception found" )
1074 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001075 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001076 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001077 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001078 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001079
kelvin-onlabd3b64892015-01-20 13:26:24 -08001080 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001081 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001082 Returns string of paths, and the cost.
1083 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001084 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001085 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001086 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1087 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001088 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001089 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001090 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001091 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001092 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001093 else:
kelvin8ec71442015-01-15 16:57:00 -08001094 path = handle.split( ";" )[ 0 ]
1095 cost = handle.split( ";" )[ 1 ]
1096 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001097 except AssertionError:
1098 main.log.exception( "" )
1099 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001100 except TypeError:
1101 main.log.exception( self.name + ": Object not as expected" )
1102 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001103 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001104 main.log.error( self.name + ": EOF exception found" )
1105 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001106 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001107 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001108 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001109 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001110
kelvin-onlabd3b64892015-01-20 13:26:24 -08001111 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001112 """
Jon Hallffb386d2014-11-21 13:43:38 -08001113 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001114 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001115 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001116 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001117 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001118 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001120 cmdStr += " -j"
1121 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001122 if handle:
1123 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001124 # TODO: Maybe make this less hardcoded
1125 # ConsistentMap Exceptions
1126 assert "org.onosproject.store.service" not in handle
1127 # Node not leader
1128 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001129 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001130 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001131 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001132 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001133 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001134 except TypeError:
1135 main.log.exception( self.name + ": Object not as expected" )
1136 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001137 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001138 main.log.error( self.name + ": EOF exception found" )
1139 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001140 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001141 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001142 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001143 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001144
kelvin-onlabd3b64892015-01-20 13:26:24 -08001145 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001146 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001147 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001148
Jon Hallefbd9792015-03-05 16:11:36 -08001149 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001150 partial mac address
1151
Jon Hall42db6dc2014-10-24 19:03:48 -04001152 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001153 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001154 try:
kelvin8ec71442015-01-15 16:57:00 -08001155 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001156 return None
1157 else:
1158 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001159 rawHosts = self.hosts()
1160 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001161 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001162 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001163 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001164 if not host:
1165 pass
1166 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001167 return host
1168 return None
Jon Hallc6793552016-01-19 14:18:37 -08001169 except ( TypeError, ValueError ):
1170 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001171 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001172 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001173 main.log.error( self.name + ": EOF exception found" )
1174 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001175 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001176 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001177 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001178 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001179
kelvin-onlabd3b64892015-01-20 13:26:24 -08001180 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001181 """
1182 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001183 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001184
andrewonlab3f0a4af2014-10-17 12:25:14 -04001185 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001186 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001187 IMPORTANT:
1188 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001189 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001190 Furthermore, it assumes that value of VLAN is '-1'
1191 Description:
kelvin8ec71442015-01-15 16:57:00 -08001192 Converts mininet hosts ( h1, h2, h3... ) into
1193 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1194 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001195 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001196 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001197
kelvin-onlabd3b64892015-01-20 13:26:24 -08001198 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001199 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001200 hostHex = hex( int( host ) ).zfill( 12 )
1201 hostHex = str( hostHex ).replace( 'x', '0' )
1202 i = iter( str( hostHex ) )
1203 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1204 hostHex = hostHex + "/-1"
1205 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001206
kelvin-onlabd3b64892015-01-20 13:26:24 -08001207 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001208
Jon Halld4d4b372015-01-28 16:02:41 -08001209 except TypeError:
1210 main.log.exception( self.name + ": Object not as expected" )
1211 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001212 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001213 main.log.error( self.name + ": EOF exception found" )
1214 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001215 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001216 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001217 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001218 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001219
You Wangbc898b82018-05-03 16:22:34 -07001220 def verifyHostLocation( self, hostIp, location ):
1221 """
1222 Description:
1223 Verify the host given is discovered in all locations expected
1224 Required:
1225 hostIp: IP address of the host
1226 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1227 Could be a string or list
1228 Returns:
1229 main.TRUE if host is discovered on all locations provided
1230 main.FALSE otherwise
1231 """
1232 import json
1233 locations = [ location ] if isinstance( location, str ) else location
1234 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1235 try:
1236 hosts = self.hosts()
1237 hosts = json.loads( hosts )
1238 targetHost = None
1239 for host in hosts:
1240 if hostIp in host[ "ipAddresses" ]:
1241 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001242 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001243 result = main.TRUE
1244 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1245 for loc in locations:
1246 discovered = False
1247 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001248 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1249 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001250 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001251 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001252 break
1253 if discovered:
1254 locationsDiscovered.remove( locDiscovered )
1255 else:
1256 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1257 result = main.FALSE
1258 if locationsDiscovered:
1259 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1260 result = main.FALSE
1261 return result
1262 except KeyError:
1263 main.log.exception( self.name + ": host data not as expected: " + hosts )
1264 return None
1265 except pexpect.EOF:
1266 main.log.error( self.name + ": EOF exception found" )
1267 main.log.error( self.name + ": " + self.handle.before )
1268 main.cleanAndExit()
1269 except Exception:
1270 main.log.exception( self.name + ": Uncaught exception" )
1271 return None
1272
You Wang53dba1e2018-02-02 17:45:44 -08001273 def verifyHostIp( self, hostList=[], prefix="" ):
1274 """
1275 Description:
1276 Verify that all hosts have IP address assigned to them
1277 Optional:
1278 hostList: If specified, verifications only happen to the hosts
1279 in hostList
1280 prefix: at least one of the ip address assigned to the host
1281 needs to have the specified prefix
1282 Returns:
1283 main.TRUE if all hosts have specific IP address assigned;
1284 main.FALSE otherwise
1285 """
1286 import json
1287 try:
1288 hosts = self.hosts()
1289 hosts = json.loads( hosts )
1290 if not hostList:
1291 hostList = [ host[ "id" ] for host in hosts ]
1292 for host in hosts:
1293 hostId = host[ "id" ]
1294 if hostId not in hostList:
1295 continue
1296 ipList = host[ "ipAddresses" ]
1297 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1298 if not ipList:
1299 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1300 else:
1301 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1302 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1303 else:
1304 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1305 hostList.remove( hostId )
1306 if hostList:
1307 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1308 return main.FALSE
1309 else:
1310 return main.TRUE
1311 except KeyError:
1312 main.log.exception( self.name + ": host data not as expected: " + hosts )
1313 return None
1314 except pexpect.EOF:
1315 main.log.error( self.name + ": EOF exception found" )
1316 main.log.error( self.name + ": " + self.handle.before )
1317 main.cleanAndExit()
1318 except Exception:
1319 main.log.exception( self.name + ": Uncaught exception" )
1320 return None
1321
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001322 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001323 """
andrewonlabe6745342014-10-17 14:29:13 -04001324 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001325 * hostIdOne: ONOS host id for host1
1326 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001327 Optional:
1328 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001329 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001330 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001331 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001332 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001333 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001334 Returns:
1335 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001336 """
andrewonlabe6745342014-10-17 14:29:13 -04001337 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001338 cmdStr = "add-host-intent "
1339 if vlanId:
1340 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001341 if setVlan:
1342 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001343 if encap:
1344 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001345 if bandwidth:
1346 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001347 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001348 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001349 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001350 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001351 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001352 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001353 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001354 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001355 else:
1356 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001357 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001358 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001359 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001360 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001361 else:
1362 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001363 main.log.debug( "Response from ONOS was: " +
1364 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001365 return None
Jon Hallc6793552016-01-19 14:18:37 -08001366 except AssertionError:
1367 main.log.exception( "" )
1368 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001369 except TypeError:
1370 main.log.exception( self.name + ": Object not as expected" )
1371 return None
andrewonlabe6745342014-10-17 14:29:13 -04001372 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001373 main.log.error( self.name + ": EOF exception found" )
1374 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001375 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001376 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001377 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001378 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001379
kelvin-onlabd3b64892015-01-20 13:26:24 -08001380 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001381 """
andrewonlab7b31d232014-10-24 13:31:47 -04001382 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001383 * ingressDevice: device id of ingress device
1384 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001385 Optional:
1386 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001387 Description:
1388 Adds an optical intent by specifying an ingress and egress device
1389 Returns:
1390 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001391 """
andrewonlab7b31d232014-10-24 13:31:47 -04001392 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001393 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1394 " " + str( egressDevice )
1395 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001396 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001397 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001398 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001399 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001400 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001401 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001402 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001403 main.log.info( "Optical intent installed between " +
1404 str( ingressDevice ) + " and " +
1405 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001406 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001407 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001408 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001409 else:
1410 main.log.error( "Error, intent ID not found" )
1411 return None
Jon Hallc6793552016-01-19 14:18:37 -08001412 except AssertionError:
1413 main.log.exception( "" )
1414 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001415 except TypeError:
1416 main.log.exception( self.name + ": Object not as expected" )
1417 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001418 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001419 main.log.error( self.name + ": EOF exception found" )
1420 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001421 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001422 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001423 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001424 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001425
kelvin-onlabd3b64892015-01-20 13:26:24 -08001426 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001427 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001428 ingressDevice,
1429 egressDevice,
1430 portIngress="",
1431 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001432 ethType="",
1433 ethSrc="",
1434 ethDst="",
1435 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001436 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001437 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001438 ipProto="",
1439 ipSrc="",
1440 ipDst="",
1441 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001442 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001443 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001444 setVlan="",
1445 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001446 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001447 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001448 * ingressDevice: device id of ingress device
1449 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001450 Optional:
1451 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001452 * ethSrc: specify ethSrc ( i.e. src mac addr )
1453 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001454 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001455 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001456 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001457 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001458 * ipSrc: specify ip source address
1459 * ipDst: specify ip destination address
1460 * tcpSrc: specify tcp source port
1461 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001462 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001463 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001464 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001465 Description:
kelvin8ec71442015-01-15 16:57:00 -08001466 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001467 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001468 Returns:
1469 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001470
Jon Halle3f39ff2015-01-13 11:50:53 -08001471 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001472 options developers provide for point-to-point
1473 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001474 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001475 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001476 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001477
Jeremy Songsterff553672016-05-12 17:06:23 -07001478 if ethType:
1479 cmd += " --ethType " + str( ethType )
1480 if ethSrc:
1481 cmd += " --ethSrc " + str( ethSrc )
1482 if ethDst:
1483 cmd += " --ethDst " + str( ethDst )
1484 if bandwidth:
1485 cmd += " --bandwidth " + str( bandwidth )
1486 if lambdaAlloc:
1487 cmd += " --lambda "
1488 if ipProto:
1489 cmd += " --ipProto " + str( ipProto )
1490 if ipSrc:
1491 cmd += " --ipSrc " + str( ipSrc )
1492 if ipDst:
1493 cmd += " --ipDst " + str( ipDst )
1494 if tcpSrc:
1495 cmd += " --tcpSrc " + str( tcpSrc )
1496 if tcpDst:
1497 cmd += " --tcpDst " + str( tcpDst )
1498 if vlanId:
1499 cmd += " -v " + str( vlanId )
1500 if setVlan:
1501 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001502 if encap:
1503 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001504 if protected:
1505 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001506
kelvin8ec71442015-01-15 16:57:00 -08001507 # Check whether the user appended the port
1508 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001509 if "/" in ingressDevice:
1510 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001511 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001512 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001513 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001514 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001515 # Would it make sense to throw an exception and exit
1516 # the test?
1517 return None
andrewonlab36af3822014-11-18 17:48:18 -05001518
kelvin8ec71442015-01-15 16:57:00 -08001519 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001520 str( ingressDevice ) + "/" +\
1521 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001522
kelvin-onlabd3b64892015-01-20 13:26:24 -08001523 if "/" in egressDevice:
1524 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001525 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001526 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001527 main.log.error( "You must specify the egress port" )
1528 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001529
kelvin8ec71442015-01-15 16:57:00 -08001530 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001531 str( egressDevice ) + "/" +\
1532 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001533
kelvin-onlab898a6c62015-01-16 14:13:53 -08001534 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001535 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001536 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001537 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001538 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001539 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001540 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001541 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001542 # TODO: print out all the options in this message?
1543 main.log.info( "Point-to-point intent installed between " +
1544 str( ingressDevice ) + " and " +
1545 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001546 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001547 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001548 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001549 else:
1550 main.log.error( "Error, intent ID not found" )
1551 return None
Jon Hallc6793552016-01-19 14:18:37 -08001552 except AssertionError:
1553 main.log.exception( "" )
1554 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001555 except TypeError:
1556 main.log.exception( self.name + ": Object not as expected" )
1557 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001558 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001559 main.log.error( self.name + ": EOF exception found" )
1560 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001561 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001562 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001563 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001564 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001565
kelvin-onlabd3b64892015-01-20 13:26:24 -08001566 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001567 self,
shahshreyac2f97072015-03-19 17:04:29 -07001568 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001569 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001570 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001571 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001572 ethType="",
1573 ethSrc="",
1574 ethDst="",
1575 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001576 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001577 ipProto="",
1578 ipSrc="",
1579 ipDst="",
1580 tcpSrc="",
1581 tcpDst="",
1582 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001583 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001584 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001585 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001586 partial=False,
1587 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001588 """
shahshreyad0c80432014-12-04 16:56:05 -08001589 Note:
shahshreya70622b12015-03-19 17:19:00 -07001590 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001591 is same. That is, all ingress devices include port numbers
1592 with a "/" or all ingress devices could specify device
1593 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001594 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001595 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001596 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001597 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001598 Optional:
1599 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001600 * ethSrc: specify ethSrc ( i.e. src mac addr )
1601 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001602 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001603 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001604 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001605 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001606 * ipSrc: specify ip source address
1607 * ipDst: specify ip destination address
1608 * tcpSrc: specify tcp source port
1609 * tcpDst: specify tcp destination port
1610 * setEthSrc: action to Rewrite Source MAC Address
1611 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001612 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001613 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001614 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001615 Description:
kelvin8ec71442015-01-15 16:57:00 -08001616 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001617 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001618 Returns:
1619 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001620
Jon Halle3f39ff2015-01-13 11:50:53 -08001621 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001622 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001623 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001624 """
shahshreyad0c80432014-12-04 16:56:05 -08001625 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001626 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001627
Jeremy Songsterff553672016-05-12 17:06:23 -07001628 if ethType:
1629 cmd += " --ethType " + str( ethType )
1630 if ethSrc:
1631 cmd += " --ethSrc " + str( ethSrc )
1632 if ethDst:
1633 cmd += " --ethDst " + str( ethDst )
1634 if bandwidth:
1635 cmd += " --bandwidth " + str( bandwidth )
1636 if lambdaAlloc:
1637 cmd += " --lambda "
1638 if ipProto:
1639 cmd += " --ipProto " + str( ipProto )
1640 if ipSrc:
1641 cmd += " --ipSrc " + str( ipSrc )
1642 if ipDst:
1643 cmd += " --ipDst " + str( ipDst )
1644 if tcpSrc:
1645 cmd += " --tcpSrc " + str( tcpSrc )
1646 if tcpDst:
1647 cmd += " --tcpDst " + str( tcpDst )
1648 if setEthSrc:
1649 cmd += " --setEthSrc " + str( setEthSrc )
1650 if setEthDst:
1651 cmd += " --setEthDst " + str( setEthDst )
1652 if vlanId:
1653 cmd += " -v " + str( vlanId )
1654 if setVlan:
1655 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001656 if partial:
1657 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001658 if encap:
1659 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001660
kelvin8ec71442015-01-15 16:57:00 -08001661 # Check whether the user appended the port
1662 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001663
1664 if portIngressList is None:
1665 for ingressDevice in ingressDeviceList:
1666 if "/" in ingressDevice:
1667 cmd += " " + str( ingressDevice )
1668 else:
1669 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001670 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001671 # TODO: perhaps more meaningful return
1672 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001673 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001674 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001675 for ingressDevice, portIngress in zip( ingressDeviceList,
1676 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001677 cmd += " " + \
1678 str( ingressDevice ) + "/" +\
1679 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001680 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001681 main.log.error( "Device list and port list does not " +
1682 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001683 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001684 if "/" in egressDevice:
1685 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001686 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001687 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001688 main.log.error( "You must specify " +
1689 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001690 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001691
kelvin8ec71442015-01-15 16:57:00 -08001692 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001693 str( egressDevice ) + "/" +\
1694 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001695 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001696 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001697 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001698 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001699 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001700 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001701 "intent" )
1702 return None
shahshreyad0c80432014-12-04 16:56:05 -08001703 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001704 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001705 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001706 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001707 else:
1708 main.log.error( "Error, intent ID not found" )
1709 return None
Jon Hallc6793552016-01-19 14:18:37 -08001710 except AssertionError:
1711 main.log.exception( "" )
1712 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001713 except TypeError:
1714 main.log.exception( self.name + ": Object not as expected" )
1715 return None
1716 except pexpect.EOF:
1717 main.log.error( self.name + ": EOF exception found" )
1718 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001719 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001720 except Exception:
1721 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001722 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001723
1724 def addSinglepointToMultipointIntent(
1725 self,
1726 ingressDevice,
1727 egressDeviceList,
1728 portIngress="",
1729 portEgressList=None,
1730 ethType="",
1731 ethSrc="",
1732 ethDst="",
1733 bandwidth="",
1734 lambdaAlloc=False,
1735 ipProto="",
1736 ipSrc="",
1737 ipDst="",
1738 tcpSrc="",
1739 tcpDst="",
1740 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001741 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001742 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001743 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001744 partial=False,
1745 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001746 """
1747 Note:
1748 This function assumes the format of all egress devices
1749 is same. That is, all egress devices include port numbers
1750 with a "/" or all egress devices could specify device
1751 ids and port numbers seperately.
1752 Required:
1753 * EgressDeviceList: List of device ids of egress device
1754 ( Atleast 2 eress devices required in the list )
1755 * ingressDevice: device id of ingress device
1756 Optional:
1757 * ethType: specify ethType
1758 * ethSrc: specify ethSrc ( i.e. src mac addr )
1759 * ethDst: specify ethDst ( i.e. dst mac addr )
1760 * bandwidth: specify bandwidth capacity of link
1761 * lambdaAlloc: if True, intent will allocate lambda
1762 for the specified intent
1763 * ipProto: specify ip protocol
1764 * ipSrc: specify ip source address
1765 * ipDst: specify ip destination address
1766 * tcpSrc: specify tcp source port
1767 * tcpDst: specify tcp destination port
1768 * setEthSrc: action to Rewrite Source MAC Address
1769 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001770 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001771 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001772 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001773 Description:
1774 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1775 specifying device id's and optional fields
1776 Returns:
1777 A string of the intent id or None on error
1778
1779 NOTE: This function may change depending on the
1780 options developers provide for singlepoint-to-multipoint
1781 intent via cli
1782 """
1783 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001784 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001785
Jeremy Songsterff553672016-05-12 17:06:23 -07001786 if ethType:
1787 cmd += " --ethType " + str( ethType )
1788 if ethSrc:
1789 cmd += " --ethSrc " + str( ethSrc )
1790 if ethDst:
1791 cmd += " --ethDst " + str( ethDst )
1792 if bandwidth:
1793 cmd += " --bandwidth " + str( bandwidth )
1794 if lambdaAlloc:
1795 cmd += " --lambda "
1796 if ipProto:
1797 cmd += " --ipProto " + str( ipProto )
1798 if ipSrc:
1799 cmd += " --ipSrc " + str( ipSrc )
1800 if ipDst:
1801 cmd += " --ipDst " + str( ipDst )
1802 if tcpSrc:
1803 cmd += " --tcpSrc " + str( tcpSrc )
1804 if tcpDst:
1805 cmd += " --tcpDst " + str( tcpDst )
1806 if setEthSrc:
1807 cmd += " --setEthSrc " + str( setEthSrc )
1808 if setEthDst:
1809 cmd += " --setEthDst " + str( setEthDst )
1810 if vlanId:
1811 cmd += " -v " + str( vlanId )
1812 if setVlan:
1813 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001814 if partial:
1815 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001816 if encap:
1817 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001818
1819 # Check whether the user appended the port
1820 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001821
kelvin-onlabb9408212015-04-01 13:34:04 -07001822 if "/" in ingressDevice:
1823 cmd += " " + str( ingressDevice )
1824 else:
1825 if not portIngress:
1826 main.log.error( "You must specify " +
1827 "the Ingress port" )
1828 return main.FALSE
1829
1830 cmd += " " +\
1831 str( ingressDevice ) + "/" +\
1832 str( portIngress )
1833
1834 if portEgressList is None:
1835 for egressDevice in egressDeviceList:
1836 if "/" in egressDevice:
1837 cmd += " " + str( egressDevice )
1838 else:
1839 main.log.error( "You must specify " +
1840 "the egress port" )
1841 # TODO: perhaps more meaningful return
1842 return main.FALSE
1843 else:
1844 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001845 for egressDevice, portEgress in zip( egressDeviceList,
1846 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001847 cmd += " " + \
1848 str( egressDevice ) + "/" +\
1849 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001850 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001851 main.log.error( "Device list and port list does not " +
1852 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001853 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001854 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001855 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001856 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001857 # If error, return error message
1858 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001859 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001860 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001861 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001862 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001863 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001864 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001865 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001866 else:
1867 main.log.error( "Error, intent ID not found" )
1868 return None
Jon Hallc6793552016-01-19 14:18:37 -08001869 except AssertionError:
1870 main.log.exception( "" )
1871 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001872 except TypeError:
1873 main.log.exception( self.name + ": Object not as expected" )
1874 return None
shahshreyad0c80432014-12-04 16:56:05 -08001875 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001876 main.log.error( self.name + ": EOF exception found" )
1877 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001878 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001879 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001880 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001881 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001882
Hari Krishna9e232602015-04-13 17:29:08 -07001883 def addMplsIntent(
1884 self,
1885 ingressDevice,
1886 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001887 ingressPort="",
1888 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001889 ethType="",
1890 ethSrc="",
1891 ethDst="",
1892 bandwidth="",
1893 lambdaAlloc=False,
1894 ipProto="",
1895 ipSrc="",
1896 ipDst="",
1897 tcpSrc="",
1898 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001899 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001900 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001901 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001902 """
1903 Required:
1904 * ingressDevice: device id of ingress device
1905 * egressDevice: device id of egress device
1906 Optional:
1907 * ethType: specify ethType
1908 * ethSrc: specify ethSrc ( i.e. src mac addr )
1909 * ethDst: specify ethDst ( i.e. dst mac addr )
1910 * bandwidth: specify bandwidth capacity of link
1911 * lambdaAlloc: if True, intent will allocate lambda
1912 for the specified intent
1913 * ipProto: specify ip protocol
1914 * ipSrc: specify ip source address
1915 * ipDst: specify ip destination address
1916 * tcpSrc: specify tcp source port
1917 * tcpDst: specify tcp destination port
1918 * ingressLabel: Ingress MPLS label
1919 * egressLabel: Egress MPLS label
1920 Description:
1921 Adds MPLS intent by
1922 specifying device id's and optional fields
1923 Returns:
1924 A string of the intent id or None on error
1925
1926 NOTE: This function may change depending on the
1927 options developers provide for MPLS
1928 intent via cli
1929 """
1930 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001931 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001932
Jeremy Songsterff553672016-05-12 17:06:23 -07001933 if ethType:
1934 cmd += " --ethType " + str( ethType )
1935 if ethSrc:
1936 cmd += " --ethSrc " + str( ethSrc )
1937 if ethDst:
1938 cmd += " --ethDst " + str( ethDst )
1939 if bandwidth:
1940 cmd += " --bandwidth " + str( bandwidth )
1941 if lambdaAlloc:
1942 cmd += " --lambda "
1943 if ipProto:
1944 cmd += " --ipProto " + str( ipProto )
1945 if ipSrc:
1946 cmd += " --ipSrc " + str( ipSrc )
1947 if ipDst:
1948 cmd += " --ipDst " + str( ipDst )
1949 if tcpSrc:
1950 cmd += " --tcpSrc " + str( tcpSrc )
1951 if tcpDst:
1952 cmd += " --tcpDst " + str( tcpDst )
1953 if ingressLabel:
1954 cmd += " --ingressLabel " + str( ingressLabel )
1955 if egressLabel:
1956 cmd += " --egressLabel " + str( egressLabel )
1957 if priority:
1958 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001959
1960 # Check whether the user appended the port
1961 # or provided it as an input
1962 if "/" in ingressDevice:
1963 cmd += " " + str( ingressDevice )
1964 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001965 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001966 main.log.error( "You must specify the ingress port" )
1967 return None
1968
1969 cmd += " " + \
1970 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001971 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001972
1973 if "/" in egressDevice:
1974 cmd += " " + str( egressDevice )
1975 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001976 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001977 main.log.error( "You must specify the egress port" )
1978 return None
1979
1980 cmd += " " +\
1981 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001982 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001983
1984 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001985 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001986 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001987 # If error, return error message
1988 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001989 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07001990 return None
1991 else:
1992 # TODO: print out all the options in this message?
1993 main.log.info( "MPLS intent installed between " +
1994 str( ingressDevice ) + " and " +
1995 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001996 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07001997 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001998 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07001999 else:
2000 main.log.error( "Error, intent ID not found" )
2001 return None
Jon Hallc6793552016-01-19 14:18:37 -08002002 except AssertionError:
2003 main.log.exception( "" )
2004 return None
Hari Krishna9e232602015-04-13 17:29:08 -07002005 except TypeError:
2006 main.log.exception( self.name + ": Object not as expected" )
2007 return None
2008 except pexpect.EOF:
2009 main.log.error( self.name + ": EOF exception found" )
2010 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002011 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002012 except Exception:
2013 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002014 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002015
Jon Hallefbd9792015-03-05 16:11:36 -08002016 def removeIntent( self, intentId, app='org.onosproject.cli',
2017 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002018 """
shahshreya1c818fc2015-02-26 13:44:08 -08002019 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07002020 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08002021 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07002022 -p or --purge: Purge the intent from the store after removal
2023
Jon Halle3f39ff2015-01-13 11:50:53 -08002024 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002025 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002026 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002027 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002028 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002029 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002030 if purge:
2031 cmdStr += " -p"
2032 if sync:
2033 cmdStr += " -s"
2034
2035 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002036 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002037 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002038 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002039 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002040 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002041 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002042 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002043 # TODO: Should this be main.TRUE
2044 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002045 except AssertionError:
2046 main.log.exception( "" )
2047 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002048 except TypeError:
2049 main.log.exception( self.name + ": Object not as expected" )
2050 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002051 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002052 main.log.error( self.name + ": EOF exception found" )
2053 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002054 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002055 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002056 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002057 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002058
YPZhangfebf7302016-05-24 16:45:56 -07002059 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002060 """
2061 Description:
2062 Remove all the intents
2063 Optional args:-
2064 -s or --sync: Waits for the removal before returning
2065 -p or --purge: Purge the intent from the store after removal
2066 Returns:
2067 Returns main.TRUE if all intents are removed, otherwise returns
2068 main.FALSE; Returns None for exception
2069 """
2070 try:
2071 cmdStr = "remove-intent"
2072 if purge:
2073 cmdStr += " -p"
2074 if sync:
2075 cmdStr += " -s"
2076
2077 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002078 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002079 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002080 assert "Command not found:" not in handle, handle
2081 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002082 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002083 return main.FALSE
2084 else:
2085 return main.TRUE
2086 except AssertionError:
2087 main.log.exception( "" )
2088 return None
2089 except TypeError:
2090 main.log.exception( self.name + ": Object not as expected" )
2091 return None
2092 except pexpect.EOF:
2093 main.log.error( self.name + ": EOF exception found" )
2094 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002095 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002096 except Exception:
2097 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002098 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002099
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002100 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002101 """
2102 Purges all WITHDRAWN Intents
2103 """
2104 try:
2105 cmdStr = "purge-intents"
2106 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002107 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002108 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002109 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002110 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002111 return main.FALSE
2112 else:
2113 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002114 except AssertionError:
2115 main.log.exception( "" )
2116 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002117 except TypeError:
2118 main.log.exception( self.name + ": Object not as expected" )
2119 return None
2120 except pexpect.EOF:
2121 main.log.error( self.name + ": EOF exception found" )
2122 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002123 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002124 except Exception:
2125 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002126 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002127
Devin Lime6fe3c42017-10-18 16:28:40 -07002128 def wipeout( self ):
2129 """
2130 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2131 """
2132 try:
2133 cmdStr = "wipe-out please"
2134 handle = self.sendline( cmdStr, timeout=60 )
2135 assert handle is not None, "Error in sendline"
2136 assert "Command not found:" not in handle, handle
2137 return main.TRUE
2138 except AssertionError:
2139 main.log.exception( "" )
2140 return None
2141 except TypeError:
2142 main.log.exception( self.name + ": Object not as expected" )
2143 return None
2144 except pexpect.EOF:
2145 main.log.error( self.name + ": EOF exception found" )
2146 main.log.error( self.name + ": " + self.handle.before )
2147 main.cleanAndExit()
2148 except Exception:
2149 main.log.exception( self.name + ": Uncaught exception!" )
2150 main.cleanAndExit()
2151
kelvin-onlabd3b64892015-01-20 13:26:24 -08002152 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002153 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002154 NOTE: This method should be used after installing application:
2155 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002156 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002157 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002158 Description:
2159 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002160 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002161 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002162 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002163 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002164 cmdStr += " -j"
2165 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002166 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002167 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002168 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002169 except AssertionError:
2170 main.log.exception( "" )
2171 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002172 except TypeError:
2173 main.log.exception( self.name + ": Object not as expected" )
2174 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002175 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002176 main.log.error( self.name + ": EOF exception found" )
2177 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002178 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002179 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002180 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002181 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002182
pingping-lin54b03372015-08-13 14:43:10 -07002183 def ipv4RouteNumber( self ):
2184 """
2185 NOTE: This method should be used after installing application:
2186 onos-app-sdnip
2187 Description:
2188 Obtain the total IPv4 routes number in the system
2189 """
2190 try:
Pratik Parab57963572017-05-09 11:37:54 -07002191 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002192 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002193 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002194 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002195 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002196 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002197 except AssertionError:
2198 main.log.exception( "" )
2199 return None
2200 except ( TypeError, ValueError ):
2201 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002202 return None
2203 except pexpect.EOF:
2204 main.log.error( self.name + ": EOF exception found" )
2205 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002206 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002207 except Exception:
2208 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002209 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002210
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002211 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002212 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002213 """
2214 Description:
2215 Obtain Bandwidth Allocation Information from ONOS cli.
2216 """
2217 try:
2218 cmdStr = "allocations"
2219 if jsonFormat:
2220 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002221 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002222 assert handle is not None, "Error in sendline"
2223 assert "Command not found:" not in handle, handle
2224 return handle
2225 except AssertionError:
2226 main.log.exception( "" )
2227 return None
2228 except ( TypeError, ValueError ):
2229 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2230 return None
2231 except pexpect.EOF:
2232 main.log.error( self.name + ": EOF exception found" )
2233 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002234 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002235 except Exception:
2236 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002237 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002238
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002239 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002240 """
andrewonlabe6745342014-10-17 14:29:13 -04002241 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002242 Obtain intents from the ONOS cli.
2243 Optional:
2244 * jsonFormat: Enable output formatting in json, default to True
2245 * summary: Whether only output the intent summary, defaults to False
2246 * type: Only output a certain type of intent. This options is valid
2247 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002248 """
andrewonlabe6745342014-10-17 14:29:13 -04002249 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002250 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002251 if summary:
2252 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002253 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002254 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002255 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002256 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002257 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002258 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002259 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002260 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002261 else:
Jon Hallff566d52016-01-15 14:45:36 -08002262 intentType = ""
2263 # IF we want the summary of a specific intent type
2264 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002265 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002266 if intentType in jsonResult.keys():
2267 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002268 else:
Jon Hallff566d52016-01-15 14:45:36 -08002269 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002270 return handle
2271 else:
2272 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002273 except AssertionError:
2274 main.log.exception( "" )
2275 return None
2276 except ( TypeError, ValueError ):
2277 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002278 return None
2279 except pexpect.EOF:
2280 main.log.error( self.name + ": EOF exception found" )
2281 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002282 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002283 except Exception:
2284 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002285 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002286
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002287 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002288 """
You Wangfdcbfc42016-05-16 12:16:53 -07002289 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002290 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002291 list of intent IDs.
2292 Parameters:
2293 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002294 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002295 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002296 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002297 accepted.
2298 Returns a list of dictionaries if a list of intent IDs is accepted,
2299 and each dictionary maps 'id' to the Intent ID and 'state' to
2300 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002301 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002302
kelvin-onlab54400a92015-02-26 18:05:51 -08002303 try:
2304 state = "State is Undefined"
2305 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002306 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002307 else:
Jon Hallc6793552016-01-19 14:18:37 -08002308 rawJson = intentsJson
2309 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002310 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002311 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002312 if intentsId == intent[ 'id' ]:
2313 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002314 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002315 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002316 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002317 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002318 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002319 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002320 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002321 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002322 for intent in parsedIntentsJson:
2323 if intentsId[ i ] == intent[ 'id' ]:
2324 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002325 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002326 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002327 break
Jon Hallefbd9792015-03-05 16:11:36 -08002328 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002329 main.log.warn( "Could not find all intents in ONOS output" )
2330 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002331 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002332 else:
Jon Hall53158082017-05-18 11:17:00 -07002333 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002334 return None
Jon Hallc6793552016-01-19 14:18:37 -08002335 except ( TypeError, ValueError ):
2336 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002337 return None
2338 except pexpect.EOF:
2339 main.log.error( self.name + ": EOF exception found" )
2340 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002341 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002342 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002343 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002344 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002345
Jon Hallf539eb92017-05-22 17:18:42 -07002346 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002347 """
2348 Description:
2349 Check intents state
2350 Required:
2351 intentsId - List of intents ID to be checked
2352 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002353 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002354 state in the list.
2355 *NOTE: You can pass in a list of expected state,
2356 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002357 Return:
Jon Hall53158082017-05-18 11:17:00 -07002358 Returns main.TRUE only if all intent are the same as expected states,
2359 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002360 """
2361 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002362 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002363 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002364
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002365 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002366 intentsDict = []
2367 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002368 if isinstance( intentsId, types.StringType ) \
2369 and intent.get( 'id' ) == intentsId:
2370 intentsDict.append( intent )
2371 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002372 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002373 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002374
2375 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002376 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002377 "getting intents state" )
2378 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002379
2380 if isinstance( expectedState, types.StringType ):
2381 for intents in intentsDict:
2382 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002383 main.log.debug( self.name + " : Intent ID - " +
2384 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002385 " actual state = " +
2386 intents.get( 'state' )
2387 + " does not equal expected state = "
2388 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002389 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002390 elif isinstance( expectedState, types.ListType ):
2391 for intents in intentsDict:
2392 if not any( state == intents.get( 'state' ) for state in
2393 expectedState ):
2394 main.log.debug( self.name + " : Intent ID - " +
2395 intents.get( 'id' ) +
2396 " actual state = " +
2397 intents.get( 'state' ) +
2398 " does not equal expected states = "
2399 + str( expectedState ) )
2400 returnValue = main.FALSE
2401
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002402 if returnValue == main.TRUE:
2403 main.log.info( self.name + ": All " +
2404 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002405 " intents are in " + str( expectedState ) +
2406 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002407 return returnValue
2408 except TypeError:
2409 main.log.exception( self.name + ": Object not as expected" )
2410 return None
2411 except pexpect.EOF:
2412 main.log.error( self.name + ": EOF exception found" )
2413 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002414 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002415 except Exception:
2416 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002417 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002418
Jon Hallf539eb92017-05-22 17:18:42 -07002419 def compareBandwidthAllocations( self, expectedAllocations ):
2420 """
2421 Description:
2422 Compare the allocated bandwidth with the given allocations
2423 Required:
2424 expectedAllocations - The expected ONOS output of the allocations command
2425 Return:
2426 Returns main.TRUE only if all intent are the same as expected states,
2427 otherwise returns main.FALSE.
2428 """
2429 # FIXME: Convert these string comparisons to object comparisons
2430 try:
2431 returnValue = main.TRUE
2432 bandwidthFailed = False
2433 rawAlloc = self.allocations()
2434 expectedFormat = StringIO( expectedAllocations )
2435 ONOSOutput = StringIO( rawAlloc )
2436 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2437 str( expectedFormat ) ) )
2438
2439 for actual, expected in izip( ONOSOutput, expectedFormat ):
2440 actual = actual.rstrip()
2441 expected = expected.rstrip()
2442 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2443 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002444 marker1 = actual.find( 'allocated' )
2445 m1 = actual[ :marker1 ]
2446 marker2 = expected.find( 'allocated' )
2447 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002448 if m1 != m2:
2449 bandwidthFailed = True
2450 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2451 bandwidthFailed = True
2452 expectedFormat.close()
2453 ONOSOutput.close()
2454
2455 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002456 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002457 returnValue = main.FALSE
2458 return returnValue
2459 except TypeError:
2460 main.log.exception( self.name + ": Object not as expected" )
2461 return None
2462 except pexpect.EOF:
2463 main.log.error( self.name + ": EOF exception found" )
2464 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002465 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002466 except Exception:
2467 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002468 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002469
You Wang66518af2016-05-16 15:32:59 -07002470 def compareIntent( self, intentDict ):
2471 """
2472 Description:
2473 Compare the intent ids and states provided in the argument with all intents in ONOS
2474 Return:
2475 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2476 Arguments:
2477 intentDict: a dictionary which maps intent ids to intent states
2478 """
2479 try:
2480 intentsRaw = self.intents()
2481 intentsJson = json.loads( intentsRaw )
2482 intentDictONOS = {}
2483 for intent in intentsJson:
2484 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002485 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002486 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002487 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002488 str( len( intentDict ) ) + " expected and " +
2489 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002490 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002491 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002492 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002493 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2494 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002495 else:
2496 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2497 main.log.debug( self.name + ": intent ID - " + intentID +
2498 " expected state is " + intentDict[ intentID ] +
2499 " but actual state is " + intentDictONOS[ intentID ] )
2500 returnValue = main.FALSE
2501 intentDictONOS.pop( intentID )
2502 if len( intentDictONOS ) > 0:
2503 returnValue = main.FALSE
2504 for intentID in intentDictONOS.keys():
2505 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002506 if returnValue == main.TRUE:
2507 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2508 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002509 except KeyError:
2510 main.log.exception( self.name + ": KeyError exception found" )
2511 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002512 except ( TypeError, ValueError ):
2513 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002514 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002515 except pexpect.EOF:
2516 main.log.error( self.name + ": EOF exception found" )
2517 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002518 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002519 except Exception:
2520 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002521 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002522
YPZhang14a4aa92016-07-15 13:37:15 -07002523 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002524 """
2525 Description:
2526 Check the number of installed intents.
2527 Optional:
2528 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002529 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002530 Return:
2531 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2532 , otherwise, returns main.FALSE.
2533 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002534
GlennRCed771242016-01-13 17:02:47 -08002535 try:
2536 cmd = "intents -s -j"
2537
2538 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002539 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002540 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002541 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002542 response = json.loads( response )
2543
2544 # get total and installed number, see if they are match
2545 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002546 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002547 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2548 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002549 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002550 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2551 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002552 return main.FALSE
2553
Jon Hallc6793552016-01-19 14:18:37 -08002554 except ( TypeError, ValueError ):
2555 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002556 return None
2557 except pexpect.EOF:
2558 main.log.error( self.name + ": EOF exception found" )
2559 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002560 if noExit:
2561 return main.FALSE
2562 else:
Devin Lim44075962017-08-11 10:56:37 -07002563 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002564 except pexpect.TIMEOUT:
2565 main.log.error( self.name + ": ONOS timeout" )
2566 return None
GlennRCed771242016-01-13 17:02:47 -08002567 except Exception:
2568 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002569 if noExit:
2570 return main.FALSE
2571 else:
Devin Lim44075962017-08-11 10:56:37 -07002572 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002573
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002574 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002575 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002576 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002577 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002578 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002579 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002580 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002581 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002582 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002583 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002584 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002585 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002586 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002587 cmdStr += " -n"
2588 cmdStr += " " + state
2589 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002590 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002591 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002592 assert "Command not found:" not in handle, handle
2593 if re.search( "Error:", handle ):
2594 main.log.error( self.name + ": flows() response: " +
2595 str( handle ) )
2596 return handle
2597 except AssertionError:
2598 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002599 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002600 except TypeError:
2601 main.log.exception( self.name + ": Object not as expected" )
2602 return None
Jon Hallc6793552016-01-19 14:18:37 -08002603 except pexpect.TIMEOUT:
2604 main.log.error( self.name + ": ONOS timeout" )
2605 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002606 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002607 main.log.error( self.name + ": EOF exception found" )
2608 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002609 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002610 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002611 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002612 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002613
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002614 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002615 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002616 count = int( count ) if count else 0
2617 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002618
Jon Halle0f0b342017-04-18 11:43:47 -07002619 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002620 """
2621 Description:
GlennRCed771242016-01-13 17:02:47 -08002622 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002623 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2624 if the count of those states is 0, which means all current flows
2625 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002626 Optional:
GlennRCed771242016-01-13 17:02:47 -08002627 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002628 Return:
2629 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002630 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002631 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002632 """
2633 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002634 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002635 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002636 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002637 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002638 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002639 if rawFlows:
2640 # if we didn't get flows or flows function return None, we should return
2641 # main.Flase
2642 checkedStates.append( json.loads( rawFlows ) )
2643 else:
2644 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002645 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002646 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002647 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002648 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002649 except TypeError:
2650 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002651 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002652
GlennRCed771242016-01-13 17:02:47 -08002653 # We want to count PENDING_ADD if isPENDING is true
2654 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002655 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002656 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002657 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002658 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002659 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002660 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002661 except ( TypeError, ValueError ):
2662 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002663 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002664
YPZhang240842b2016-05-17 12:00:50 -07002665 except AssertionError:
2666 main.log.exception( "" )
2667 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002668 except pexpect.TIMEOUT:
2669 main.log.error( self.name + ": ONOS timeout" )
2670 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002671 except pexpect.EOF:
2672 main.log.error( self.name + ": EOF exception found" )
2673 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002674 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002675 except Exception:
2676 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002677 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002678
GlennRCed771242016-01-13 17:02:47 -08002679 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002680 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002681 """
andrewonlab87852b02014-11-19 18:44:19 -05002682 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002683 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002684 a specific point-to-point intent definition
2685 Required:
GlennRCed771242016-01-13 17:02:47 -08002686 * ingress: specify source dpid
2687 * egress: specify destination dpid
2688 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002689 Optional:
GlennRCed771242016-01-13 17:02:47 -08002690 * offset: the keyOffset is where the next batch of intents
2691 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002692 * noExit: If set to True, TestON will not exit if any error when issus command
2693 * getResponse: If set to True, function will return ONOS response.
2694
GlennRCed771242016-01-13 17:02:47 -08002695 Returns: If failed to push test intents, it will returen None,
2696 if successful, return true.
2697 Timeout expection will return None,
2698 TypeError will return false
2699 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002700 """
andrewonlab87852b02014-11-19 18:44:19 -05002701 try:
GlennRCed771242016-01-13 17:02:47 -08002702 if background:
2703 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002704 else:
GlennRCed771242016-01-13 17:02:47 -08002705 back = ""
2706 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002707 ingress,
2708 egress,
2709 batchSize,
2710 offset,
2711 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002712 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002713 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002714 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002715 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002716 if getResponse:
2717 return response
2718
GlennRCed771242016-01-13 17:02:47 -08002719 # TODO: We should handle if there is failure in installation
2720 return main.TRUE
2721
Jon Hallc6793552016-01-19 14:18:37 -08002722 except AssertionError:
2723 main.log.exception( "" )
2724 return None
GlennRCed771242016-01-13 17:02:47 -08002725 except pexpect.TIMEOUT:
2726 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002727 return None
andrewonlab87852b02014-11-19 18:44:19 -05002728 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002729 main.log.error( self.name + ": EOF exception found" )
2730 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002731 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002732 except TypeError:
2733 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002734 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002735 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002736 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002737 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002738
YPZhangebf9eb52016-05-12 15:20:24 -07002739 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002740 """
2741 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002742 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002743 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002744 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002745 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002746 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002747
YPZhangb5d3f832016-01-23 22:54:26 -08002748 try:
YPZhange3109a72016-02-02 11:25:37 -08002749 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002750 cmd = "flows -c added"
2751 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2752 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002753 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002754 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002755 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002756 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002757 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002758 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002759 return None
2760 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002761
You Wangd3cb2ce2016-05-16 14:01:24 -07002762 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002763 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002764 return None
2765 except pexpect.EOF:
2766 main.log.error( self.name + ": EOF exception found" )
2767 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002768 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002769 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002770 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002771 except pexpect.TIMEOUT:
2772 main.log.error( self.name + ": ONOS timeout" )
2773 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002774 except Exception:
2775 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002776 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002777 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002778 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002779
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002780 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002781 """
2782 Description:
2783 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002784 Optional:
2785 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002786 Return:
2787 The number of intents
2788 """
2789 try:
2790 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002791 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002792 if response is None:
2793 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002794 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002795 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002796 except ( TypeError, ValueError ):
2797 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002798 return None
2799 except pexpect.EOF:
2800 main.log.error( self.name + ": EOF exception found" )
2801 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002802 if noExit:
2803 return -1
2804 else:
Devin Lim44075962017-08-11 10:56:37 -07002805 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002806 except Exception:
2807 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002808 if noExit:
2809 return -1
2810 else:
Devin Lim44075962017-08-11 10:56:37 -07002811 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002812
kelvin-onlabd3b64892015-01-20 13:26:24 -08002813 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002814 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002815 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002816 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002817 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002818 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002819 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002820 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002821 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002822 cmdStr += " -j"
2823 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002824 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002825 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002826 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002827 except AssertionError:
2828 main.log.exception( "" )
2829 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002830 except TypeError:
2831 main.log.exception( self.name + ": Object not as expected" )
2832 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002833 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002834 main.log.error( self.name + ": EOF exception found" )
2835 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002836 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002837 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002838 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002839 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002840
kelvin-onlabd3b64892015-01-20 13:26:24 -08002841 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002842 """
2843 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002844 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002845 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002846 """
andrewonlab867212a2014-10-22 20:13:38 -04002847 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002848 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002849 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002850 cmdStr += " -j"
2851 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002852 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002853 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002854 if handle:
2855 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002856 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002857 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002858 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002859 else:
2860 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002861 except AssertionError:
2862 main.log.exception( "" )
2863 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002864 except TypeError:
2865 main.log.exception( self.name + ": Object not as expected" )
2866 return None
andrewonlab867212a2014-10-22 20:13:38 -04002867 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002868 main.log.error( self.name + ": EOF exception found" )
2869 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002870 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002871 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002872 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002873 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002874
kelvin8ec71442015-01-15 16:57:00 -08002875 # Wrapper functions ****************
2876 # Wrapper functions use existing driver
2877 # functions and extends their use case.
2878 # For example, we may use the output of
2879 # a normal driver function, and parse it
2880 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002881
kelvin-onlabd3b64892015-01-20 13:26:24 -08002882 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002883 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002884 Description:
2885 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002886 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002887 try:
kelvin8ec71442015-01-15 16:57:00 -08002888 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002889 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002890 if intentsStr is None:
2891 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002892 # Convert to a dictionary
2893 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002894 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002895 for intent in intents:
2896 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002897 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002898 except TypeError:
2899 main.log.exception( self.name + ": Object not as expected" )
2900 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002901 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002902 main.log.error( self.name + ": EOF exception found" )
2903 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002904 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002905 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002906 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002907 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002908
You Wang3c276252016-09-21 15:21:36 -07002909 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002910 """
2911 Determine the number of flow rules for the given device id that are
2912 in the added state
You Wang3c276252016-09-21 15:21:36 -07002913 Params:
2914 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002915 """
2916 try:
You Wang3c276252016-09-21 15:21:36 -07002917 if core:
2918 cmdStr = "flows any " + str( deviceId ) + " | " +\
2919 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2920 else:
2921 cmdStr = "flows any " + str( deviceId ) + " | " +\
2922 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002923 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002924 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002925 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002926 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002927 except AssertionError:
2928 main.log.exception( "" )
2929 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002930 except pexpect.EOF:
2931 main.log.error( self.name + ": EOF exception found" )
2932 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002933 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002934 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002935 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002936 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002937
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002938 def groupAddedCount( self, deviceId, core=False ):
2939 """
2940 Determine the number of group rules for the given device id that are
2941 in the added state
2942 Params:
2943 core: if True, only return the number of core groups added
2944 """
2945 try:
2946 if core:
2947 cmdStr = "groups any " + str( deviceId ) + " | " +\
2948 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2949 else:
2950 cmdStr = "groups any " + str( deviceId ) + " | " +\
2951 "grep 'state=ADDED' | wc -l"
2952 handle = self.sendline( cmdStr )
2953 assert handle is not None, "Error in sendline"
2954 assert "Command not found:" not in handle, handle
2955 return handle
2956 except AssertionError:
2957 main.log.exception( "" )
2958 return None
2959 except pexpect.EOF:
2960 main.log.error( self.name + ": EOF exception found" )
2961 main.log.error( self.name + ": " + self.handle.before )
2962 main.cleanAndExit()
2963 except Exception:
2964 main.log.exception( self.name + ": Uncaught exception!" )
2965 main.cleanAndExit()
2966
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002967 def addStaticRoute( self, subnet, intf):
2968 """
2969 Adds a static route to onos.
2970 Params:
2971 subnet: The subnet reaching through this route
2972 intf: The interface this route is reachable through
2973 """
2974 try:
2975 cmdStr = "route-add " + subnet + " " + intf
2976 handle = self.sendline( cmdStr )
2977 assert handle is not None, "Error in sendline"
2978 assert "Command not found:" not in handle, handle
2979 return handle
2980 except AssertionError:
2981 main.log.exception( "" )
2982 return None
2983 except pexpect.EOF:
2984 main.log.error( self.name + ": EOF exception found" )
2985 main.log.error( self.name + ": " + self.handle.before )
2986 main.cleanAndExit()
2987 except Exception:
2988 main.log.exception( self.name + ": Uncaught exception!" )
2989 main.cleanAndExit()
2990
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002991 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
2992 """
2993 Description:
2994 Check whether the number of groups for the given device id that
2995 are in ADDED state is bigger than minGroupCount.
2996 Required:
2997 * deviceId: device id to check the number of added group rules
2998 Optional:
2999 * minGroupCount: the number of groups to compare
3000 * core: if True, only check the number of core groups added
3001 * comparison: if 0, compare with greater than minFlowCount
3002 * if 1, compare with equal to minFlowCount
3003 Return:
3004 Returns the number of groups if it is bigger than minGroupCount,
3005 returns main.FALSE otherwise.
3006 """
3007 count = self.groupAddedCount( deviceId, core )
3008 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003009 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003010 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
3011
You Wangc02f3be2018-05-18 12:14:23 -07003012 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003013 """
3014 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07003015 deviceId: Id of the device from which we retrieve groups
3016 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003017 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003018 try:
You Wangc02f3be2018-05-18 12:14:23 -07003019 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
3020 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003021 assert handle is not None, "Error in sendline"
3022 assert "Command not found:" not in handle, handle
3023 return handle
3024 except AssertionError:
3025 main.log.exception( "" )
3026 return None
3027 except TypeError:
3028 main.log.exception( self.name + ": Object not as expected" )
3029 return None
3030 except pexpect.EOF:
3031 main.log.error( self.name + ": EOF exception found" )
3032 main.log.error( self.name + ": " + self.handle.before )
3033 main.cleanAndExit()
3034 except Exception:
3035 main.log.exception( self.name + ": Uncaught exception!" )
3036 main.cleanAndExit()
3037
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003038 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003039 """
3040 Description:
3041 Check whether the number of flow rules for the given device id that
3042 are in ADDED state is bigger than minFlowCount.
3043 Required:
3044 * deviceId: device id to check the number of added flow rules
3045 Optional:
3046 * minFlowCount: the number of flow rules to compare
3047 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003048 * comparison: if 0, compare with greater than minFlowCount
3049 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003050 Return:
3051 Returns the number of flow rules if it is bigger than minFlowCount,
3052 returns main.FALSE otherwise.
3053 """
3054 count = self.flowAddedCount( deviceId, core )
3055 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003056 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003057 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003058
kelvin-onlabd3b64892015-01-20 13:26:24 -08003059 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003060 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003061 Use 'devices' function to obtain list of all devices
3062 and parse the result to obtain a list of all device
3063 id's. Returns this list. Returns empty list if no
3064 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003065 List is ordered sequentially
3066
andrewonlab3e15ead2014-10-15 14:21:34 -04003067 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003068 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003069 the ids. By obtaining the list of device ids on the fly,
3070 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003071 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003072 try:
kelvin8ec71442015-01-15 16:57:00 -08003073 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003074 devicesStr = self.devices( jsonFormat=False )
3075 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003076
kelvin-onlabd3b64892015-01-20 13:26:24 -08003077 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003078 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003079 return idList
kelvin8ec71442015-01-15 16:57:00 -08003080
3081 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003082 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003083 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003084 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003085 # Split list further into arguments before and after string
3086 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003087 # append to idList
3088 for arg in tempList:
3089 idList.append( arg.split( "id=" )[ 1 ] )
3090 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003091
Jon Halld4d4b372015-01-28 16:02:41 -08003092 except TypeError:
3093 main.log.exception( self.name + ": Object not as expected" )
3094 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003095 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003096 main.log.error( self.name + ": EOF exception found" )
3097 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003098 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003099 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003100 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003101 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003102
kelvin-onlabd3b64892015-01-20 13:26:24 -08003103 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003104 """
andrewonlab7c211572014-10-15 16:45:20 -04003105 Uses 'nodes' function to obtain list of all nodes
3106 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003107 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003108 Returns:
3109 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003110 """
andrewonlab7c211572014-10-15 16:45:20 -04003111 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003112 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003113 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003114 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003115 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003116 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003117 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003118 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003119 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003120 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003121 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003122 except ( TypeError, ValueError ):
3123 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003124 return None
andrewonlab7c211572014-10-15 16:45:20 -04003125 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003126 main.log.error( self.name + ": EOF exception found" )
3127 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003128 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003129 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003130 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003131 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003132
kelvin-onlabd3b64892015-01-20 13:26:24 -08003133 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003134 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003135 Return the first device from the devices api whose 'id' contains 'dpid'
3136 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003137 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003138 try:
kelvin8ec71442015-01-15 16:57:00 -08003139 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003140 return None
3141 else:
kelvin8ec71442015-01-15 16:57:00 -08003142 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003143 rawDevices = self.devices()
3144 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003145 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003146 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003147 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3148 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003149 return device
3150 return None
Jon Hallc6793552016-01-19 14:18:37 -08003151 except ( TypeError, ValueError ):
3152 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003153 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003154 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003155 main.log.error( self.name + ": EOF exception found" )
3156 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003157 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003158 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003159 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003160 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003161
You Wang24139872016-05-03 11:48:47 -07003162 def getTopology( self, topologyOutput ):
3163 """
3164 Definition:
3165 Loads a json topology output
3166 Return:
3167 topology = current ONOS topology
3168 """
3169 import json
3170 try:
3171 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003172 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003173 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003174 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003175 except ( TypeError, ValueError ):
3176 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3177 return None
You Wang24139872016-05-03 11:48:47 -07003178 except pexpect.EOF:
3179 main.log.error( self.name + ": EOF exception found" )
3180 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003181 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003182 except Exception:
3183 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003184 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003185
Pier6a0c4de2018-03-18 16:01:30 -07003186 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003187 """
Jon Hallefbd9792015-03-05 16:11:36 -08003188 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003189 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003190 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003191
Flavio Castro82ee2f62016-06-07 15:04:12 -07003192 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003193 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003194 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003195 logLevel = level to log to.
3196 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003197
Jon Hallefbd9792015-03-05 16:11:36 -08003198 Returns: main.TRUE if the number of switches and links are correct,
3199 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003200 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003201 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003202 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003203 try:
You Wang13310252016-07-31 10:56:14 -07003204 summary = self.summary()
3205 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003206 except ( TypeError, ValueError ):
3207 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3208 return main.ERROR
3209 try:
3210 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003211 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003212 return main.ERROR
3213 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003214 # Is the number of switches is what we expected
3215 devices = topology.get( 'devices', False )
3216 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003217 nodes = summary.get( 'nodes', False )
3218 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003219 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003220 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003221 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003222 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003223 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3224 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003225 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003226 output = output + "The number of links and switches match "\
3227 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003228 result = main.TRUE
3229 else:
You Wang24139872016-05-03 11:48:47 -07003230 output = output + \
3231 "The number of links and switches does not match " + \
3232 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003233 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003234 output = output + "\n ONOS sees %i devices" % int( devices )
3235 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003236 if int( numolink ) > 0:
3237 output = output + "and %i links " % int( links )
3238 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003239 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003240 output = output + "and %i controllers " % int( nodes )
3241 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003242 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003243 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003244 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003245 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003246 else:
You Wang24139872016-05-03 11:48:47 -07003247 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003248 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003249 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003250 main.log.error( self.name + ": EOF exception found" )
3251 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003252 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003253 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003254 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003255 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003256
kelvin-onlabd3b64892015-01-20 13:26:24 -08003257 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003258 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003259 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003260 deviceId must be the id of a device as seen in the onos devices command
3261 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003262 role must be either master, standby, or none
3263
Jon Halle3f39ff2015-01-13 11:50:53 -08003264 Returns:
3265 main.TRUE or main.FALSE based on argument verification and
3266 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003267 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003268 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003269 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003270 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003271 cmdStr = "device-role " +\
3272 str( deviceId ) + " " +\
3273 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003274 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003275 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003276 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003277 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003278 if re.search( "Error", handle ):
3279 # end color output to escape any colours
3280 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003281 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003282 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003283 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003284 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003285 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003286 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003287 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003288 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003289 except AssertionError:
3290 main.log.exception( "" )
3291 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003292 except TypeError:
3293 main.log.exception( self.name + ": Object not as expected" )
3294 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003295 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003296 main.log.error( self.name + ": EOF exception found" )
3297 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003298 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003299 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003300 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003301 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003302
kelvin-onlabd3b64892015-01-20 13:26:24 -08003303 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003304 """
Jon Hall0dd09952018-04-19 09:59:11 -07003305 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003306 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003307 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003308 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003309 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003310 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003311 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003312 cmdStr += " -j"
3313 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003314 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003315 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003316 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003317 except AssertionError:
3318 main.log.exception( "" )
3319 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003320 except TypeError:
3321 main.log.exception( self.name + ": Object not as expected" )
3322 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003323 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003324 main.log.error( self.name + ": EOF exception found" )
3325 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003326 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003327 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003328 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003329 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003330
kelvin-onlabd3b64892015-01-20 13:26:24 -08003331 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003332 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003333 CLI command to get the current leader for the Election test application
3334 NOTE: Requires installation of the onos-app-election feature
3335 Returns: Node IP of the leader if one exists
3336 None if none exists
3337 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003338 """
Jon Hall94fd0472014-12-08 11:52:42 -08003339 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003340 cmdStr = "election-test-leader"
3341 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003342 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003343 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003344 # Leader
3345 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003346 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003347 nodeSearch = re.search( leaderPattern, response )
3348 if nodeSearch:
3349 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003350 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003351 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003352 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003353 # no leader
3354 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003355 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003356 nullSearch = re.search( nullPattern, response )
3357 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003358 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003359 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003360 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003361 # error
Jon Hall0e240372018-05-02 11:21:57 -07003362 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003363 ": " + "unexpected response" )
3364 main.log.error( repr( response ) )
3365 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003366 except AssertionError:
3367 main.log.exception( "" )
3368 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003369 except TypeError:
3370 main.log.exception( self.name + ": Object not as expected" )
3371 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003372 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003373 main.log.error( self.name + ": EOF exception found" )
3374 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003375 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003376 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003377 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003378 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003379
kelvin-onlabd3b64892015-01-20 13:26:24 -08003380 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003381 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003382 CLI command to run for leadership of the Election test application.
3383 NOTE: Requires installation of the onos-app-election feature
3384 Returns: Main.TRUE on success
3385 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003386 """
Jon Hall94fd0472014-12-08 11:52:42 -08003387 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003388 cmdStr = "election-test-run"
3389 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003390 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003391 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003392 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003393 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003394 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003395 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003396 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003397 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003398 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003399 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003400 # error
Jon Hall0e240372018-05-02 11:21:57 -07003401 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003402 ": " + "unexpected response" )
3403 main.log.error( repr( response ) )
3404 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003405 except AssertionError:
3406 main.log.exception( "" )
3407 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003408 except TypeError:
3409 main.log.exception( self.name + ": Object not as expected" )
3410 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003411 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003412 main.log.error( self.name + ": EOF exception found" )
3413 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003414 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003415 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003416 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003417 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003418
kelvin-onlabd3b64892015-01-20 13:26:24 -08003419 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003420 """
Jon Hall94fd0472014-12-08 11:52:42 -08003421 * CLI command to withdraw the local node from leadership election for
3422 * the Election test application.
3423 #NOTE: Requires installation of the onos-app-election feature
3424 Returns: Main.TRUE on success
3425 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003426 """
Jon Hall94fd0472014-12-08 11:52:42 -08003427 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003428 cmdStr = "election-test-withdraw"
3429 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003430 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003431 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003432 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003433 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003434 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003435 if re.search( successPattern, response ):
3436 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003437 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003438 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003439 # error
Jon Hall0e240372018-05-02 11:21:57 -07003440 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003441 self.name + ": " + "unexpected response" )
3442 main.log.error( repr( response ) )
3443 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003444 except AssertionError:
3445 main.log.exception( "" )
3446 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003447 except TypeError:
3448 main.log.exception( self.name + ": Object not as expected" )
3449 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003450 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003451 main.log.error( self.name + ": EOF exception found" )
3452 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003453 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003454 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003455 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003456 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003457
kelvin8ec71442015-01-15 16:57:00 -08003458 def getDevicePortsEnabledCount( self, dpid ):
3459 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003460 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003461 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003462 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003463 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003464 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3465 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003466 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003467 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003468 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003469 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003470 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003471 return output
Jon Hallc6793552016-01-19 14:18:37 -08003472 except AssertionError:
3473 main.log.exception( "" )
3474 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003475 except TypeError:
3476 main.log.exception( self.name + ": Object not as expected" )
3477 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003478 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003479 main.log.error( self.name + ": EOF exception found" )
3480 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003481 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003482 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003483 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003484 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003485
kelvin8ec71442015-01-15 16:57:00 -08003486 def getDeviceLinksActiveCount( self, dpid ):
3487 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003488 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003489 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003490 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003491 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003492 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3493 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003494 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003495 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003496 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003497 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003498 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003499 return output
Jon Hallc6793552016-01-19 14:18:37 -08003500 except AssertionError:
3501 main.log.exception( "" )
3502 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003503 except TypeError:
3504 main.log.exception( self.name + ": Object not as expected" )
3505 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003506 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003507 main.log.error( self.name + ": EOF exception found" )
3508 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003509 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003510 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003511 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003512 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003513
kelvin8ec71442015-01-15 16:57:00 -08003514 def getAllIntentIds( self ):
3515 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003516 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003517 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003518 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003519 cmdStr = "onos:intents | grep id="
3520 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003521 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003522 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003523 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003524 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003525 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003526 return output
Jon Hallc6793552016-01-19 14:18:37 -08003527 except AssertionError:
3528 main.log.exception( "" )
3529 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003530 except TypeError:
3531 main.log.exception( self.name + ": Object not as expected" )
3532 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003533 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003534 main.log.error( self.name + ": EOF exception found" )
3535 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003536 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003537 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003538 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003539 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003540
Jon Hall73509952015-02-24 16:42:56 -08003541 def intentSummary( self ):
3542 """
Jon Hallefbd9792015-03-05 16:11:36 -08003543 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003544 """
3545 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003546 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003547 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003548 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003549 states.append( intent.get( 'state', None ) )
3550 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003551 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003552 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003553 except ( TypeError, ValueError ):
3554 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003555 return None
3556 except pexpect.EOF:
3557 main.log.error( self.name + ": EOF exception found" )
3558 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003559 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003560 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003561 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003562 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003563
Jon Hall61282e32015-03-19 11:34:11 -07003564 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003565 """
3566 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003567 Optional argument:
3568 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003569 """
Jon Hall63604932015-02-26 17:09:50 -08003570 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003571 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003572 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003573 cmdStr += " -j"
3574 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003575 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003576 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003577 return output
Jon Hallc6793552016-01-19 14:18:37 -08003578 except AssertionError:
3579 main.log.exception( "" )
3580 return None
Jon Hall63604932015-02-26 17:09:50 -08003581 except TypeError:
3582 main.log.exception( self.name + ": Object not as expected" )
3583 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003584 except pexpect.EOF:
3585 main.log.error( self.name + ": EOF exception found" )
3586 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003587 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003588 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003589 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003590 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003591
acsmarsa4a4d1e2015-07-10 16:01:24 -07003592 def leaderCandidates( self, jsonFormat=True ):
3593 """
3594 Returns the output of the leaders -c command.
3595 Optional argument:
3596 * jsonFormat - boolean indicating if you want output in json
3597 """
3598 try:
3599 cmdStr = "onos:leaders -c"
3600 if jsonFormat:
3601 cmdStr += " -j"
3602 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003603 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003604 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003605 return output
Jon Hallc6793552016-01-19 14:18:37 -08003606 except AssertionError:
3607 main.log.exception( "" )
3608 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003609 except TypeError:
3610 main.log.exception( self.name + ": Object not as expected" )
3611 return None
3612 except pexpect.EOF:
3613 main.log.error( self.name + ": EOF exception found" )
3614 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003615 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003616 except Exception:
3617 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003618 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003619
Jon Hallc6793552016-01-19 14:18:37 -08003620 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003621 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003622 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003623 topic parameter and an empty list if the topic doesn't exist
3624 If no leader is elected leader in the returned list will be "none"
3625 Returns None if there is a type error processing the json object
3626 """
3627 try:
Jon Hall6e709752016-02-01 13:38:46 -08003628 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003629 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003630 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003631 assert "Command not found:" not in rawOutput, rawOutput
3632 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003633 results = []
3634 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003635 if dict[ "topic" ] == topic:
3636 leader = dict[ "leader" ]
3637 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003638 results.append( leader )
3639 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003640 return results
Jon Hallc6793552016-01-19 14:18:37 -08003641 except AssertionError:
3642 main.log.exception( "" )
3643 return None
3644 except ( TypeError, ValueError ):
3645 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003646 return None
3647 except pexpect.EOF:
3648 main.log.error( self.name + ": EOF exception found" )
3649 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003650 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003651 except Exception:
3652 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003653 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003654
Jon Hall61282e32015-03-19 11:34:11 -07003655 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003656 """
3657 Returns the output of the intent Pending map.
3658 """
Jon Hall63604932015-02-26 17:09:50 -08003659 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003660 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003661 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003662 cmdStr += " -j"
3663 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003664 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003665 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003666 return output
Jon Hallc6793552016-01-19 14:18:37 -08003667 except AssertionError:
3668 main.log.exception( "" )
3669 return None
Jon Hall63604932015-02-26 17:09:50 -08003670 except TypeError:
3671 main.log.exception( self.name + ": Object not as expected" )
3672 return None
3673 except pexpect.EOF:
3674 main.log.error( self.name + ": EOF exception found" )
3675 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003676 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003677 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003678 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003679 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003680
Jon Hall2c8959e2016-12-16 12:17:34 -08003681 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003682 """
3683 Returns the output of the raft partitions command for ONOS.
3684 """
Jon Hall61282e32015-03-19 11:34:11 -07003685 # Sample JSON
3686 # {
3687 # "leader": "tcp://10.128.30.11:7238",
3688 # "members": [
3689 # "tcp://10.128.30.11:7238",
3690 # "tcp://10.128.30.17:7238",
3691 # "tcp://10.128.30.13:7238",
3692 # ],
3693 # "name": "p1",
3694 # "term": 3
3695 # },
Jon Hall63604932015-02-26 17:09:50 -08003696 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003697 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003698 if candidates:
3699 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003700 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003701 cmdStr += " -j"
3702 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003703 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003704 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003705 return output
Jon Hallc6793552016-01-19 14:18:37 -08003706 except AssertionError:
3707 main.log.exception( "" )
3708 return None
Jon Hall63604932015-02-26 17:09:50 -08003709 except TypeError:
3710 main.log.exception( self.name + ": Object not as expected" )
3711 return None
3712 except pexpect.EOF:
3713 main.log.error( self.name + ": EOF exception found" )
3714 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003715 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003716 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003717 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003718 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003719
Jon Halle9f909e2016-09-23 10:43:12 -07003720 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003721 """
3722 Returns the output of the apps command for ONOS. This command lists
3723 information about installed ONOS applications
3724 """
3725 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003726 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003727 # "description":"ONOS OpenFlow protocol southbound providers",
3728 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003729 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003730 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003731 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003732 if summary:
3733 cmdStr += " -s"
3734 if active:
3735 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003736 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003737 cmdStr += " -j"
3738 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003739 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003740 assert "Command not found:" not in output, output
3741 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003742 return output
Jon Hallbe379602015-03-24 13:39:32 -07003743 # FIXME: look at specific exceptions/Errors
3744 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003745 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003746 return None
3747 except TypeError:
3748 main.log.exception( self.name + ": Object not as expected" )
3749 return None
3750 except pexpect.EOF:
3751 main.log.error( self.name + ": EOF exception found" )
3752 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003753 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003754 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003755 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003756 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003757
You Wangcdc51fe2018-08-12 17:14:56 -07003758 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003759 """
3760 Uses the onos:apps cli command to return the status of an application.
3761 Returns:
3762 "ACTIVE" - If app is installed and activated
3763 "INSTALLED" - If app is installed and deactivated
3764 "UNINSTALLED" - If app is not installed
3765 None - on error
3766 """
Jon Hall146f1522015-03-24 15:33:24 -07003767 try:
3768 if not isinstance( appName, types.StringType ):
3769 main.log.error( self.name + ".appStatus(): appName must be" +
3770 " a string" )
3771 return None
3772 output = self.apps( jsonFormat=True )
3773 appsJson = json.loads( output )
3774 state = None
3775 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003776 if appName == app.get( 'name' ):
3777 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003778 break
3779 if state == "ACTIVE" or state == "INSTALLED":
3780 return state
3781 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003782 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003783 return "UNINSTALLED"
3784 elif state:
3785 main.log.error( "Unexpected state from 'onos:apps': " +
3786 str( state ) )
3787 return state
Jon Hallc6793552016-01-19 14:18:37 -08003788 except ( TypeError, ValueError ):
3789 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003790 return None
3791 except pexpect.EOF:
3792 main.log.error( self.name + ": EOF exception found" )
3793 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003794 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003795 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003796 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003797 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003798
Jon Hallbe379602015-03-24 13:39:32 -07003799 def app( self, appName, option ):
3800 """
3801 Interacts with the app command for ONOS. This command manages
3802 application inventory.
3803 """
Jon Hallbe379602015-03-24 13:39:32 -07003804 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003805 # Validate argument types
3806 valid = True
3807 if not isinstance( appName, types.StringType ):
3808 main.log.error( self.name + ".app(): appName must be a " +
3809 "string" )
3810 valid = False
3811 if not isinstance( option, types.StringType ):
3812 main.log.error( self.name + ".app(): option must be a string" )
3813 valid = False
3814 if not valid:
3815 return main.FALSE
3816 # Validate Option
3817 option = option.lower()
3818 # NOTE: Install may become a valid option
3819 if option == "activate":
3820 pass
3821 elif option == "deactivate":
3822 pass
3823 elif option == "uninstall":
3824 pass
3825 else:
3826 # Invalid option
3827 main.log.error( "The ONOS app command argument only takes " +
3828 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003829 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003830 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003831 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003832 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003833 assert output is not None, "Error in sendline"
3834 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003835 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003836 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003837 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003838 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003839 elif "No such application" in output:
3840 main.log.error( "The application '" + appName +
3841 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003842 return main.FALSE
3843 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003844 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003845 str( output ) )
3846 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003847 elif "Unsupported command:" in output:
3848 main.log.error( "Incorrect command given to 'app': " +
3849 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003850 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003851 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003852 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003853 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003854 except AssertionError:
3855 main.log.exception( self.name + ": AssertionError exception found" )
3856 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003857 except TypeError:
3858 main.log.exception( self.name + ": Object not as expected" )
3859 return main.ERROR
3860 except pexpect.EOF:
3861 main.log.error( self.name + ": EOF exception found" )
3862 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003863 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003864 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003865 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003866 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003867
Jon Hallbd16b922015-03-26 17:53:15 -07003868 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003869 """
3870 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003871 appName is the hierarchical app name, not the feature name
3872 If check is True, method will check the status of the app after the
3873 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003874 Returns main.TRUE if the command was successfully sent
3875 main.FALSE if the cli responded with an error or given
3876 incorrect input
3877 """
3878 try:
3879 if not isinstance( appName, types.StringType ):
3880 main.log.error( self.name + ".activateApp(): appName must be" +
3881 " a string" )
3882 return main.FALSE
3883 status = self.appStatus( appName )
3884 if status == "INSTALLED":
3885 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003886 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003887 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003888 status = self.appStatus( appName )
3889 if status == "ACTIVE":
3890 return main.TRUE
3891 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003892 main.log.debug( "The state of application " +
3893 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003894 time.sleep( 1 )
3895 return main.FALSE
3896 else: # not 'check' or command didn't succeed
3897 return response
Jon Hall146f1522015-03-24 15:33:24 -07003898 elif status == "ACTIVE":
3899 return main.TRUE
3900 elif status == "UNINSTALLED":
3901 main.log.error( self.name + ": Tried to activate the " +
3902 "application '" + appName + "' which is not " +
3903 "installed." )
3904 else:
3905 main.log.error( "Unexpected return value from appStatus: " +
3906 str( status ) )
3907 return main.ERROR
3908 except TypeError:
3909 main.log.exception( self.name + ": Object not as expected" )
3910 return main.ERROR
3911 except pexpect.EOF:
3912 main.log.error( self.name + ": EOF exception found" )
3913 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003914 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003915 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003916 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003917 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003918
Jon Hallbd16b922015-03-26 17:53:15 -07003919 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003920 """
3921 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003922 appName is the hierarchical app name, not the feature name
3923 If check is True, method will check the status of the app after the
3924 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003925 Returns main.TRUE if the command was successfully sent
3926 main.FALSE if the cli responded with an error or given
3927 incorrect input
3928 """
3929 try:
3930 if not isinstance( appName, types.StringType ):
3931 main.log.error( self.name + ".deactivateApp(): appName must " +
3932 "be a string" )
3933 return main.FALSE
3934 status = self.appStatus( appName )
3935 if status == "INSTALLED":
3936 return main.TRUE
3937 elif status == "ACTIVE":
3938 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003939 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003940 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003941 status = self.appStatus( appName )
3942 if status == "INSTALLED":
3943 return main.TRUE
3944 else:
3945 time.sleep( 1 )
3946 return main.FALSE
3947 else: # not check or command didn't succeed
3948 return response
Jon Hall146f1522015-03-24 15:33:24 -07003949 elif status == "UNINSTALLED":
3950 main.log.warn( self.name + ": Tried to deactivate the " +
3951 "application '" + appName + "' which is not " +
3952 "installed." )
3953 return main.TRUE
3954 else:
3955 main.log.error( "Unexpected return value from appStatus: " +
3956 str( status ) )
3957 return main.ERROR
3958 except TypeError:
3959 main.log.exception( self.name + ": Object not as expected" )
3960 return main.ERROR
3961 except pexpect.EOF:
3962 main.log.error( self.name + ": EOF exception found" )
3963 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003964 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003965 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003966 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003967 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003968
Jon Hallbd16b922015-03-26 17:53:15 -07003969 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003970 """
3971 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003972 appName is the hierarchical app name, not the feature name
3973 If check is True, method will check the status of the app after the
3974 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003975 Returns main.TRUE if the command was successfully sent
3976 main.FALSE if the cli responded with an error or given
3977 incorrect input
3978 """
3979 # TODO: check with Thomas about the state machine for apps
3980 try:
3981 if not isinstance( appName, types.StringType ):
3982 main.log.error( self.name + ".uninstallApp(): appName must " +
3983 "be a string" )
3984 return main.FALSE
3985 status = self.appStatus( appName )
3986 if status == "INSTALLED":
3987 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003988 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003989 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003990 status = self.appStatus( appName )
3991 if status == "UNINSTALLED":
3992 return main.TRUE
3993 else:
3994 time.sleep( 1 )
3995 return main.FALSE
3996 else: # not check or command didn't succeed
3997 return response
Jon Hall146f1522015-03-24 15:33:24 -07003998 elif status == "ACTIVE":
3999 main.log.warn( self.name + ": Tried to uninstall the " +
4000 "application '" + appName + "' which is " +
4001 "currently active." )
4002 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004003 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004004 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004005 status = self.appStatus( appName )
4006 if status == "UNINSTALLED":
4007 return main.TRUE
4008 else:
4009 time.sleep( 1 )
4010 return main.FALSE
4011 else: # not check or command didn't succeed
4012 return response
Jon Hall146f1522015-03-24 15:33:24 -07004013 elif status == "UNINSTALLED":
4014 return main.TRUE
4015 else:
4016 main.log.error( "Unexpected return value from appStatus: " +
4017 str( status ) )
4018 return main.ERROR
4019 except TypeError:
4020 main.log.exception( self.name + ": Object not as expected" )
4021 return main.ERROR
4022 except pexpect.EOF:
4023 main.log.error( self.name + ": EOF exception found" )
4024 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004025 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004026 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004027 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004028 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004029
4030 def appIDs( self, jsonFormat=True ):
4031 """
4032 Show the mappings between app id and app names given by the 'app-ids'
4033 cli command
4034 """
4035 try:
4036 cmdStr = "app-ids"
4037 if jsonFormat:
4038 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004039 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004040 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004041 assert "Command not found:" not in output, output
4042 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004043 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004044 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004045 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004046 return None
4047 except TypeError:
4048 main.log.exception( self.name + ": Object not as expected" )
4049 return None
4050 except pexpect.EOF:
4051 main.log.error( self.name + ": EOF exception found" )
4052 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004053 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004054 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004055 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004056 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004057
4058 def appToIDCheck( self ):
4059 """
4060 This method will check that each application's ID listed in 'apps' is
4061 the same as the ID listed in 'app-ids'. The check will also check that
4062 there are no duplicate IDs issued. Note that an app ID should be
4063 a globaly unique numerical identifier for app/app-like features. Once
4064 an ID is registered, the ID is never freed up so that if an app is
4065 reinstalled it will have the same ID.
4066
4067 Returns: main.TRUE if the check passes and
4068 main.FALSE if the check fails or
4069 main.ERROR if there is some error in processing the test
4070 """
4071 try:
Jon Hall0e240372018-05-02 11:21:57 -07004072 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004073 rawJson = self.appIDs( jsonFormat=True )
4074 if rawJson:
4075 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004076 else:
Jon Hall0e240372018-05-02 11:21:57 -07004077 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4078 return main.FALSE
4079
4080 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004081 rawJson = self.apps( jsonFormat=True )
4082 if rawJson:
4083 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004084 else:
Jon Hallc6793552016-01-19 14:18:37 -08004085 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004086 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004087
Jon Hallbd16b922015-03-26 17:53:15 -07004088 result = main.TRUE
4089 for app in apps:
4090 appID = app.get( 'id' )
4091 if appID is None:
4092 main.log.error( "Error parsing app: " + str( app ) )
4093 result = main.FALSE
4094 appName = app.get( 'name' )
4095 if appName is None:
4096 main.log.error( "Error parsing app: " + str( app ) )
4097 result = main.FALSE
4098 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004099 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004100 if not current: # if ids doesn't have this id
4101 result = main.FALSE
4102 main.log.error( "'app-ids' does not have the ID for " +
4103 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004104 main.log.debug( "apps command returned: " + str( app ) +
4105 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004106 elif len( current ) > 1:
4107 # there is more than one app with this ID
4108 result = main.FALSE
4109 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004110 elif not current[ 0 ][ 'name' ] == appName:
4111 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004112 result = main.FALSE
4113 main.log.error( "'app-ids' has " + str( currentName ) +
4114 " registered under id:" + str( appID ) +
4115 " but 'apps' has " + str( appName ) )
4116 else:
4117 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004118
Jon Hallbd16b922015-03-26 17:53:15 -07004119 # now make sure that app-ids has no duplicates
4120 idsList = []
4121 namesList = []
4122 for item in ids:
4123 idsList.append( item[ 'id' ] )
4124 namesList.append( item[ 'name' ] )
4125 if len( idsList ) != len( set( idsList ) ) or\
4126 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004127 main.log.error( "'app-ids' has some duplicate entries: \n"
4128 + json.dumps( ids,
4129 sort_keys=True,
4130 indent=4,
4131 separators=( ',', ': ' ) ) )
4132 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004133 return result
Jon Hallc6793552016-01-19 14:18:37 -08004134 except ( TypeError, ValueError ):
4135 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004136 return main.ERROR
4137 except pexpect.EOF:
4138 main.log.error( self.name + ": EOF exception found" )
4139 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004140 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004141 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004142 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004143 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004144
Jon Hallfb760a02015-04-13 15:35:03 -07004145 def getCfg( self, component=None, propName=None, short=False,
4146 jsonFormat=True ):
4147 """
4148 Get configuration settings from onos cli
4149 Optional arguments:
4150 component - Optionally only list configurations for a specific
4151 component. If None, all components with configurations
4152 are displayed. Case Sensitive string.
4153 propName - If component is specified, propName option will show
4154 only this specific configuration from that component.
4155 Case Sensitive string.
4156 jsonFormat - Returns output as json. Note that this will override
4157 the short option
4158 short - Short, less verbose, version of configurations.
4159 This is overridden by the json option
4160 returns:
4161 Output from cli as a string or None on error
4162 """
4163 try:
4164 baseStr = "cfg"
4165 cmdStr = " get"
4166 componentStr = ""
4167 if component:
4168 componentStr += " " + component
4169 if propName:
4170 componentStr += " " + propName
4171 if jsonFormat:
4172 baseStr += " -j"
4173 elif short:
4174 baseStr += " -s"
4175 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004176 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004177 assert "Command not found:" not in output, output
4178 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004179 return output
4180 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004181 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004182 return None
4183 except TypeError:
4184 main.log.exception( self.name + ": Object not as expected" )
4185 return None
4186 except pexpect.EOF:
4187 main.log.error( self.name + ": EOF exception found" )
4188 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004189 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004190 except Exception:
4191 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004192 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004193
4194 def setCfg( self, component, propName, value=None, check=True ):
4195 """
4196 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004197 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004198 component - The case sensitive name of the component whose
4199 property is to be set
4200 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004201 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004202 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004203 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004204 check - Boolean, Check whether the option was successfully set this
4205 only applies when a value is given.
4206 returns:
4207 main.TRUE on success or main.FALSE on failure. If check is False,
4208 will return main.TRUE unless there is an error
4209 """
4210 try:
4211 baseStr = "cfg"
4212 cmdStr = " set " + str( component ) + " " + str( propName )
4213 if value is not None:
4214 cmdStr += " " + str( value )
4215 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004216 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004217 assert "Command not found:" not in output, output
4218 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004219 if value and check:
4220 results = self.getCfg( component=str( component ),
4221 propName=str( propName ),
4222 jsonFormat=True )
4223 # Check if current value is what we just set
4224 try:
4225 jsonOutput = json.loads( results )
4226 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004227 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004228 main.log.exception( "Error parsing cfg output" )
4229 main.log.error( "output:" + repr( results ) )
4230 return main.FALSE
4231 if current == str( value ):
4232 return main.TRUE
4233 return main.FALSE
4234 return main.TRUE
4235 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004236 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004237 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004238 except ( TypeError, ValueError ):
4239 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004240 return main.FALSE
4241 except pexpect.EOF:
4242 main.log.error( self.name + ": EOF exception found" )
4243 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004244 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004245 except Exception:
4246 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004247 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004248
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004249 def distPrimitivesSend( self, cmd ):
4250 """
4251 Function to handle sending cli commands for the distributed primitives test app
4252
4253 This command will catch some exceptions and retry the command on some
4254 specific store exceptions.
4255
4256 Required arguments:
4257 cmd - The command to send to the cli
4258 returns:
4259 string containing the cli output
4260 None on Error
4261 """
4262 try:
4263 output = self.sendline( cmd )
4264 try:
4265 assert output is not None, "Error in sendline"
4266 # TODO: Maybe make this less hardcoded
4267 # ConsistentMap Exceptions
4268 assert "org.onosproject.store.service" not in output
4269 # Node not leader
4270 assert "java.lang.IllegalStateException" not in output
4271 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004272 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004273 "command: " + str( output ) )
4274 retryTime = 30 # Conservative time, given by Madan
4275 main.log.info( "Waiting " + str( retryTime ) +
4276 "seconds before retrying." )
4277 time.sleep( retryTime ) # Due to change in mastership
4278 output = self.sendline( cmd )
4279 assert output is not None, "Error in sendline"
4280 assert "Command not found:" not in output, output
4281 assert "Error executing command" not in output, output
4282 main.log.info( self.name + ": " + output )
4283 return output
4284 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004285 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004286 return None
4287 except TypeError:
4288 main.log.exception( self.name + ": Object not as expected" )
4289 return None
4290 except pexpect.EOF:
4291 main.log.error( self.name + ": EOF exception found" )
4292 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004293 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004294 except Exception:
4295 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004296 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004297
Jon Hall390696c2015-05-05 17:13:41 -07004298 def setTestAdd( self, setName, values ):
4299 """
4300 CLI command to add elements to a distributed set.
4301 Arguments:
4302 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004303 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004304 Example usages:
4305 setTestAdd( "set1", "a b c" )
4306 setTestAdd( "set2", "1" )
4307 returns:
4308 main.TRUE on success OR
4309 main.FALSE if elements were already in the set OR
4310 main.ERROR on error
4311 """
4312 try:
4313 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004314 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004315 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4316 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004317 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004318 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004319 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004320 return main.FALSE
4321 else:
4322 main.log.error( self.name + ": setTestAdd did not" +
4323 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004324 main.log.debug( self.name + " actual: " + repr( output ) )
4325 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004326 except TypeError:
4327 main.log.exception( self.name + ": Object not as expected" )
4328 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004329 except Exception:
4330 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004331 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004332
4333 def setTestRemove( self, setName, values, clear=False, retain=False ):
4334 """
4335 CLI command to remove elements from a distributed set.
4336 Required arguments:
4337 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004338 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004339 Optional arguments:
4340 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004341 retain - Retain only the given values. (intersection of the
4342 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004343 returns:
4344 main.TRUE on success OR
4345 main.FALSE if the set was not changed OR
4346 main.ERROR on error
4347 """
4348 try:
4349 cmdStr = "set-test-remove "
4350 if clear:
4351 cmdStr += "-c " + str( setName )
4352 elif retain:
4353 cmdStr += "-r " + str( setName ) + " " + str( values )
4354 else:
4355 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004356 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004357 if clear:
4358 pattern = "Set " + str( setName ) + " cleared"
4359 if re.search( pattern, output ):
4360 return main.TRUE
4361 elif retain:
4362 positivePattern = str( setName ) + " was pruned to contain " +\
4363 "only elements of set \[(.*)\]"
4364 negativePattern = str( setName ) + " was not changed by " +\
4365 "retaining only elements of the set " +\
4366 "\[(.*)\]"
4367 if re.search( positivePattern, output ):
4368 return main.TRUE
4369 elif re.search( negativePattern, output ):
4370 return main.FALSE
4371 else:
4372 positivePattern = "\[(.*)\] was removed from the set " +\
4373 str( setName )
4374 if ( len( values.split() ) == 1 ):
4375 negativePattern = "\[(.*)\] was not in set " +\
4376 str( setName )
4377 else:
4378 negativePattern = "No element of \[(.*)\] was in set " +\
4379 str( setName )
4380 if re.search( positivePattern, output ):
4381 return main.TRUE
4382 elif re.search( negativePattern, output ):
4383 return main.FALSE
4384 main.log.error( self.name + ": setTestRemove did not" +
4385 " match expected output" )
4386 main.log.debug( self.name + " expected: " + pattern )
4387 main.log.debug( self.name + " actual: " + repr( output ) )
4388 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004389 except TypeError:
4390 main.log.exception( self.name + ": Object not as expected" )
4391 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004392 except Exception:
4393 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004394 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004395
4396 def setTestGet( self, setName, values="" ):
4397 """
4398 CLI command to get the elements in a distributed set.
4399 Required arguments:
4400 setName - The name of the set to remove from.
4401 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004402 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004403 returns:
4404 main.ERROR on error OR
4405 A list of elements in the set if no optional arguments are
4406 supplied OR
4407 A tuple containing the list then:
4408 main.FALSE if the given values are not in the set OR
4409 main.TRUE if the given values are in the set OR
4410 """
4411 try:
4412 values = str( values ).strip()
4413 setName = str( setName ).strip()
4414 length = len( values.split() )
4415 containsCheck = None
4416 # Patterns to match
4417 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004418 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004419 containsTrue = "Set " + setName + " contains the value " + values
4420 containsFalse = "Set " + setName + " did not contain the value " +\
4421 values
4422 containsAllTrue = "Set " + setName + " contains the the subset " +\
4423 setPattern
4424 containsAllFalse = "Set " + setName + " did not contain the the" +\
4425 " subset " + setPattern
4426
4427 cmdStr = "set-test-get "
4428 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004429 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004430 if length == 0:
4431 match = re.search( pattern, output )
4432 else: # if given values
4433 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004434 patternTrue = pattern + "\r\n" + containsTrue
4435 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004436 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004437 patternTrue = pattern + "\r\n" + containsAllTrue
4438 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004439 matchTrue = re.search( patternTrue, output )
4440 matchFalse = re.search( patternFalse, output )
4441 if matchTrue:
4442 containsCheck = main.TRUE
4443 match = matchTrue
4444 elif matchFalse:
4445 containsCheck = main.FALSE
4446 match = matchFalse
4447 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004448 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004449 "expected output" )
4450 main.log.debug( self.name + " expected: " + pattern )
4451 main.log.debug( self.name + " actual: " + repr( output ) )
4452 match = None
4453 if match:
4454 setMatch = match.group( 1 )
4455 if setMatch == '':
4456 setList = []
4457 else:
4458 setList = setMatch.split( ", " )
4459 if length > 0:
4460 return ( setList, containsCheck )
4461 else:
4462 return setList
4463 else: # no match
4464 main.log.error( self.name + ": setTestGet did not" +
4465 " match expected output" )
4466 main.log.debug( self.name + " expected: " + pattern )
4467 main.log.debug( self.name + " actual: " + repr( output ) )
4468 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004469 except TypeError:
4470 main.log.exception( self.name + ": Object not as expected" )
4471 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004472 except Exception:
4473 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004474 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004475
4476 def setTestSize( self, setName ):
4477 """
4478 CLI command to get the elements in a distributed set.
4479 Required arguments:
4480 setName - The name of the set to remove from.
4481 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004482 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004483 None on error
4484 """
4485 try:
4486 # TODO: Should this check against the number of elements returned
4487 # and then return true/false based on that?
4488 setName = str( setName ).strip()
4489 # Patterns to match
4490 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004491 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004492 setPattern
4493 cmdStr = "set-test-get -s "
4494 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004495 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004496 if output:
4497 match = re.search( pattern, output )
4498 if match:
4499 setSize = int( match.group( 1 ) )
4500 setMatch = match.group( 2 )
4501 if len( setMatch.split() ) == setSize:
4502 main.log.info( "The size returned by " + self.name +
4503 " matches the number of elements in " +
4504 "the returned set" )
4505 else:
4506 main.log.error( "The size returned by " + self.name +
4507 " does not match the number of " +
4508 "elements in the returned set." )
4509 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004510 else: # no match
4511 main.log.error( self.name + ": setTestGet did not" +
4512 " match expected output" )
4513 main.log.debug( self.name + " expected: " + pattern )
4514 main.log.debug( self.name + " actual: " + repr( output ) )
4515 return None
Jon Hall390696c2015-05-05 17:13:41 -07004516 except TypeError:
4517 main.log.exception( self.name + ": Object not as expected" )
4518 return None
Jon Hall390696c2015-05-05 17:13:41 -07004519 except Exception:
4520 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004521 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004522
Jon Hall80daded2015-05-27 16:07:00 -07004523 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004524 """
4525 Command to list the various counters in the system.
4526 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004527 if jsonFormat, a string of the json object returned by the cli
4528 command
4529 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004530 None on error
4531 """
Jon Hall390696c2015-05-05 17:13:41 -07004532 try:
Jon Hall390696c2015-05-05 17:13:41 -07004533 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004534 if jsonFormat:
4535 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004536 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004537 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004538 assert "Command not found:" not in output, output
4539 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004540 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004541 return output
Jon Hall390696c2015-05-05 17:13:41 -07004542 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004543 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004544 return None
Jon Hall390696c2015-05-05 17:13:41 -07004545 except TypeError:
4546 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004547 return None
Jon Hall390696c2015-05-05 17:13:41 -07004548 except pexpect.EOF:
4549 main.log.error( self.name + ": EOF exception found" )
4550 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004551 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004552 except Exception:
4553 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004554 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004555
Jon Hall935db192016-04-19 00:22:04 -07004556 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004557 """
Jon Halle1a3b752015-07-22 13:02:46 -07004558 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004559 Required arguments:
4560 counter - The name of the counter to increment.
4561 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004562 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004563 returns:
4564 integer value of the counter or
4565 None on Error
4566 """
4567 try:
4568 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004569 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004570 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004571 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004572 if delta != 1:
4573 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004574 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004575 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004576 match = re.search( pattern, output )
4577 if match:
4578 return int( match.group( 1 ) )
4579 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004580 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004581 " match expected output." )
4582 main.log.debug( self.name + " expected: " + pattern )
4583 main.log.debug( self.name + " actual: " + repr( output ) )
4584 return None
Jon Hall390696c2015-05-05 17:13:41 -07004585 except TypeError:
4586 main.log.exception( self.name + ": Object not as expected" )
4587 return None
Jon Hall390696c2015-05-05 17:13:41 -07004588 except Exception:
4589 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004590 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004591
Jon Hall935db192016-04-19 00:22:04 -07004592 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004593 """
4594 CLI command to get a distributed counter then add a delta to it.
4595 Required arguments:
4596 counter - The name of the counter to increment.
4597 Optional arguments:
4598 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004599 returns:
4600 integer value of the counter or
4601 None on Error
4602 """
4603 try:
4604 counter = str( counter )
4605 delta = int( delta )
4606 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004607 cmdStr += counter
4608 if delta != 1:
4609 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004610 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004611 pattern = counter + " was updated to (-?\d+)"
4612 match = re.search( pattern, output )
4613 if match:
4614 return int( match.group( 1 ) )
4615 else:
4616 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4617 " match expected output." )
4618 main.log.debug( self.name + " expected: " + pattern )
4619 main.log.debug( self.name + " actual: " + repr( output ) )
4620 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004621 except TypeError:
4622 main.log.exception( self.name + ": Object not as expected" )
4623 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004624 except Exception:
4625 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004626 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004627
4628 def valueTestGet( self, valueName ):
4629 """
4630 CLI command to get the value of an atomic value.
4631 Required arguments:
4632 valueName - The name of the value to get.
4633 returns:
4634 string value of the value or
4635 None on Error
4636 """
4637 try:
4638 valueName = str( valueName )
4639 cmdStr = "value-test "
4640 operation = "get"
4641 cmdStr = "value-test {} {}".format( valueName,
4642 operation )
4643 output = self.distPrimitivesSend( cmdStr )
4644 pattern = "(\w+)"
4645 match = re.search( pattern, output )
4646 if match:
4647 return match.group( 1 )
4648 else:
4649 main.log.error( self.name + ": valueTestGet did not" +
4650 " match expected output." )
4651 main.log.debug( self.name + " expected: " + pattern )
4652 main.log.debug( self.name + " actual: " + repr( output ) )
4653 return None
4654 except TypeError:
4655 main.log.exception( self.name + ": Object not as expected" )
4656 return None
4657 except Exception:
4658 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004659 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004660
4661 def valueTestSet( self, valueName, newValue ):
4662 """
4663 CLI command to set the value of an atomic value.
4664 Required arguments:
4665 valueName - The name of the value to set.
4666 newValue - The value to assign to the given value.
4667 returns:
4668 main.TRUE on success or
4669 main.ERROR on Error
4670 """
4671 try:
4672 valueName = str( valueName )
4673 newValue = str( newValue )
4674 operation = "set"
4675 cmdStr = "value-test {} {} {}".format( valueName,
4676 operation,
4677 newValue )
4678 output = self.distPrimitivesSend( cmdStr )
4679 if output is not None:
4680 return main.TRUE
4681 else:
4682 return main.ERROR
4683 except TypeError:
4684 main.log.exception( self.name + ": Object not as expected" )
4685 return main.ERROR
4686 except Exception:
4687 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004688 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004689
4690 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4691 """
4692 CLI command to compareAndSet the value of an atomic value.
4693 Required arguments:
4694 valueName - The name of the value.
4695 oldValue - Compare the current value of the atomic value to this
4696 newValue - If the value equals oldValue, set the value to newValue
4697 returns:
4698 main.TRUE on success or
4699 main.FALSE on failure or
4700 main.ERROR on Error
4701 """
4702 try:
4703 valueName = str( valueName )
4704 oldValue = str( oldValue )
4705 newValue = str( newValue )
4706 operation = "compareAndSet"
4707 cmdStr = "value-test {} {} {} {}".format( valueName,
4708 operation,
4709 oldValue,
4710 newValue )
4711 output = self.distPrimitivesSend( cmdStr )
4712 pattern = "(\w+)"
4713 match = re.search( pattern, output )
4714 if match:
4715 result = match.group( 1 )
4716 if result == "true":
4717 return main.TRUE
4718 elif result == "false":
4719 return main.FALSE
4720 else:
4721 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4722 " match expected output." )
4723 main.log.debug( self.name + " expected: " + pattern )
4724 main.log.debug( self.name + " actual: " + repr( output ) )
4725 return main.ERROR
4726 except TypeError:
4727 main.log.exception( self.name + ": Object not as expected" )
4728 return main.ERROR
4729 except Exception:
4730 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004731 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004732
4733 def valueTestGetAndSet( self, valueName, newValue ):
4734 """
4735 CLI command to getAndSet the value of an atomic value.
4736 Required arguments:
4737 valueName - The name of the value to get.
4738 newValue - The value to assign to the given value
4739 returns:
4740 string value of the value or
4741 None on Error
4742 """
4743 try:
4744 valueName = str( valueName )
4745 cmdStr = "value-test "
4746 operation = "getAndSet"
4747 cmdStr += valueName + " " + operation
4748 cmdStr = "value-test {} {} {}".format( valueName,
4749 operation,
4750 newValue )
4751 output = self.distPrimitivesSend( cmdStr )
4752 pattern = "(\w+)"
4753 match = re.search( pattern, output )
4754 if match:
4755 return match.group( 1 )
4756 else:
4757 main.log.error( self.name + ": valueTestGetAndSet did not" +
4758 " match expected output." )
4759 main.log.debug( self.name + " expected: " + pattern )
4760 main.log.debug( self.name + " actual: " + repr( output ) )
4761 return None
4762 except TypeError:
4763 main.log.exception( self.name + ": Object not as expected" )
4764 return None
4765 except Exception:
4766 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004767 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004768
4769 def valueTestDestroy( self, valueName ):
4770 """
4771 CLI command to destroy an atomic value.
4772 Required arguments:
4773 valueName - The name of the value to destroy.
4774 returns:
4775 main.TRUE on success or
4776 main.ERROR on Error
4777 """
4778 try:
4779 valueName = str( valueName )
4780 cmdStr = "value-test "
4781 operation = "destroy"
4782 cmdStr += valueName + " " + operation
4783 output = self.distPrimitivesSend( cmdStr )
4784 if output is not None:
4785 return main.TRUE
4786 else:
4787 return main.ERROR
4788 except TypeError:
4789 main.log.exception( self.name + ": Object not as expected" )
4790 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004791 except Exception:
4792 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004793 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004794
YPZhangfebf7302016-05-24 16:45:56 -07004795 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004796 """
4797 Description: Execute summary command in onos
4798 Returns: json object ( summary -j ), returns main.FALSE if there is
4799 no output
4800
4801 """
4802 try:
4803 cmdStr = "summary"
4804 if jsonFormat:
4805 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004806 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004807 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004808 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004809 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004810 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004811 if not handle:
4812 main.log.error( self.name + ": There is no output in " +
4813 "summary command" )
4814 return main.FALSE
4815 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004816 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004817 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004818 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004819 except TypeError:
4820 main.log.exception( self.name + ": Object not as expected" )
4821 return None
4822 except pexpect.EOF:
4823 main.log.error( self.name + ": EOF exception found" )
4824 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004825 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004826 except Exception:
4827 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004828 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004829
Jon Hall935db192016-04-19 00:22:04 -07004830 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004831 """
4832 CLI command to get the value of a key in a consistent map using
4833 transactions. This a test function and can only get keys from the
4834 test map hard coded into the cli command
4835 Required arguments:
4836 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004837 returns:
4838 The string value of the key or
4839 None on Error
4840 """
4841 try:
4842 keyName = str( keyName )
4843 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004844 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004845 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004846 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4847 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004848 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004849 return None
4850 else:
4851 match = re.search( pattern, output )
4852 if match:
4853 return match.groupdict()[ 'value' ]
4854 else:
4855 main.log.error( self.name + ": transactionlMapGet did not" +
4856 " match expected output." )
4857 main.log.debug( self.name + " expected: " + pattern )
4858 main.log.debug( self.name + " actual: " + repr( output ) )
4859 return None
4860 except TypeError:
4861 main.log.exception( self.name + ": Object not as expected" )
4862 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004863 except Exception:
4864 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004865 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004866
Jon Hall935db192016-04-19 00:22:04 -07004867 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004868 """
4869 CLI command to put a value into 'numKeys' number of keys in a
4870 consistent map using transactions. This a test function and can only
4871 put into keys named 'Key#' of the test map hard coded into the cli command
4872 Required arguments:
4873 numKeys - Number of keys to add the value to
4874 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004875 returns:
4876 A dictionary whose keys are the name of the keys put into the map
4877 and the values of the keys are dictionaries whose key-values are
4878 'value': value put into map and optionaly
4879 'oldValue': Previous value in the key or
4880 None on Error
4881
4882 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004883 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4884 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004885 """
4886 try:
4887 numKeys = str( numKeys )
4888 value = str( value )
4889 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004890 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004891 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004892 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4893 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4894 results = {}
4895 for line in output.splitlines():
4896 new = re.search( newPattern, line )
4897 updated = re.search( updatedPattern, line )
4898 if new:
4899 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4900 elif updated:
4901 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004902 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004903 else:
4904 main.log.error( self.name + ": transactionlMapGet did not" +
4905 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004906 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4907 newPattern,
4908 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004909 main.log.debug( self.name + " actual: " + repr( output ) )
4910 return results
Jon Hall0e240372018-05-02 11:21:57 -07004911 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004912 main.log.exception( self.name + ": Object not as expected" )
4913 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004914 except Exception:
4915 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004916 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004917
acsmarsdaea66c2015-09-03 11:44:06 -07004918 def maps( self, jsonFormat=True ):
4919 """
4920 Description: Returns result of onos:maps
4921 Optional:
4922 * jsonFormat: enable json formatting of output
4923 """
4924 try:
4925 cmdStr = "maps"
4926 if jsonFormat:
4927 cmdStr += " -j"
4928 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004929 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004930 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004931 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004932 except AssertionError:
4933 main.log.exception( "" )
4934 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004935 except TypeError:
4936 main.log.exception( self.name + ": Object not as expected" )
4937 return None
4938 except pexpect.EOF:
4939 main.log.error( self.name + ": EOF exception found" )
4940 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004941 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004942 except Exception:
4943 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004944 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004945
4946 def getSwController( self, uri, jsonFormat=True ):
4947 """
4948 Descrition: Gets the controller information from the device
4949 """
4950 try:
4951 cmd = "device-controllers "
4952 if jsonFormat:
4953 cmd += "-j "
4954 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004955 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004956 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004957 return response
Jon Hallc6793552016-01-19 14:18:37 -08004958 except AssertionError:
4959 main.log.exception( "" )
4960 return None
GlennRC050596c2015-11-18 17:06:41 -08004961 except TypeError:
4962 main.log.exception( self.name + ": Object not as expected" )
4963 return None
4964 except pexpect.EOF:
4965 main.log.error( self.name + ": EOF exception found" )
4966 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004967 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004968 except Exception:
4969 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004970 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004971
4972 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4973 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004974 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004975
4976 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004977 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08004978 ip - String or List: The ip address of the controller.
4979 This parameter can be formed in a couple of different ways.
4980 VALID:
4981 10.0.0.1 - just the ip address
4982 tcp:10.0.0.1 - the protocol and the ip address
4983 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4984 so that you can add controllers with different
4985 protocols and ports
4986 INVALID:
4987 10.0.0.1:6653 - this is not supported by ONOS
4988
4989 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4990 port - The port number.
4991 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4992
4993 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4994 """
4995 try:
4996 cmd = "device-setcontrollers"
4997
4998 if jsonFormat:
4999 cmd += " -j"
5000 cmd += " " + uri
5001 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005002 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08005003 for item in ip:
5004 if ":" in item:
5005 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005006 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08005007 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005008 elif "." in sitem[ 1 ]:
5009 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08005010 else:
5011 main.log.error( "Malformed entry: " + item )
5012 raise TypeError
5013 else:
5014 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08005015 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07005016 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005017 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005018 if "Error" in response:
5019 main.log.error( response )
5020 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005021 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005022 except AssertionError:
5023 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005024 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005025 except TypeError:
5026 main.log.exception( self.name + ": Object not as expected" )
5027 return main.FALSE
5028 except pexpect.EOF:
5029 main.log.error( self.name + ": EOF exception found" )
5030 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005031 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005032 except Exception:
5033 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005034 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005035
5036 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005037 '''
GlennRC20fc6522015-12-23 23:26:57 -08005038 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005039 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005040 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005041 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005042 Returns:
5043 Returns main.FALSE if an exception is thrown or an error is present
5044 in the response. Otherwise, returns main.TRUE.
5045 NOTE:
5046 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005047 '''
GlennRC20fc6522015-12-23 23:26:57 -08005048 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005049 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005050 deviceStr = device
5051 device = []
5052 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005053
5054 for d in device:
5055 time.sleep( 1 )
5056 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005057 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005058 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005059 if "Error" in response:
5060 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5061 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005062 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005063 except AssertionError:
5064 main.log.exception( "" )
5065 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005066 except TypeError:
5067 main.log.exception( self.name + ": Object not as expected" )
5068 return main.FALSE
5069 except pexpect.EOF:
5070 main.log.error( self.name + ": EOF exception found" )
5071 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005072 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005073 except Exception:
5074 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005075 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005076
5077 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005078 '''
GlennRC20fc6522015-12-23 23:26:57 -08005079 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005080 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005081 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005082 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005083 Returns:
5084 Returns main.FALSE if an exception is thrown or an error is present
5085 in the response. Otherwise, returns main.TRUE.
5086 NOTE:
5087 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005088 '''
GlennRC20fc6522015-12-23 23:26:57 -08005089 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005090 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005091 host = list( host )
5092
5093 for h in host:
5094 time.sleep( 1 )
5095 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005096 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005097 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005098 if "Error" in response:
5099 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5100 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005101 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005102 except AssertionError:
5103 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005104 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005105 except TypeError:
5106 main.log.exception( self.name + ": Object not as expected" )
5107 return main.FALSE
5108 except pexpect.EOF:
5109 main.log.error( self.name + ": EOF exception found" )
5110 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005111 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005112 except Exception:
5113 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005114 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005115
YPZhangfebf7302016-05-24 16:45:56 -07005116 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005117 '''
GlennRCed771242016-01-13 17:02:47 -08005118 Description:
5119 Bring link down or up in the null-provider.
5120 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005121 begin - (string) One end of a device or switch.
5122 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005123 returns:
5124 main.TRUE if no exceptions were thrown and no Errors are
5125 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005126 '''
GlennRCed771242016-01-13 17:02:47 -08005127 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005128 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005129 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005130 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005131 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005132 if "Error" in response or "Failure" in response:
5133 main.log.error( response )
5134 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005135 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005136 except AssertionError:
5137 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005138 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005139 except TypeError:
5140 main.log.exception( self.name + ": Object not as expected" )
5141 return main.FALSE
5142 except pexpect.EOF:
5143 main.log.error( self.name + ": EOF exception found" )
5144 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005145 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005146 except Exception:
5147 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005148 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005149
Jon Hall2c8959e2016-12-16 12:17:34 -08005150 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005151 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005152 Description:
5153 Changes the state of port in an OF switch by means of the
5154 PORTSTATUS OF messages.
5155 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005156 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5157 port - (string) target port in the device. Ex: '2'
5158 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005159 returns:
5160 main.TRUE if no exceptions were thrown and no Errors are
5161 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005162 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005163 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005164 state = state.lower()
5165 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005166 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005167 response = self.sendline( cmd, showResponse=True )
5168 assert response is not None, "Error in sendline"
5169 assert "Command not found:" not in response, response
5170 if "Error" in response or "Failure" in response:
5171 main.log.error( response )
5172 return main.FALSE
5173 return main.TRUE
5174 except AssertionError:
5175 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005176 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005177 except TypeError:
5178 main.log.exception( self.name + ": Object not as expected" )
5179 return main.FALSE
5180 except pexpect.EOF:
5181 main.log.error( self.name + ": EOF exception found" )
5182 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005183 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005184 except Exception:
5185 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005186 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005187
5188 def logSet( self, level="INFO", app="org.onosproject" ):
5189 """
5190 Set the logging level to lvl for a specific app
5191 returns main.TRUE on success
5192 returns main.FALSE if Error occurred
5193 if noExit is True, TestON will not exit, but clean up
5194 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5195 Level defaults to INFO
5196 """
5197 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005198 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -08005199 self.handle.expect( self.karafPrompt )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005200
5201 response = self.handle.before
5202 if re.search( "Error", response ):
5203 return main.FALSE
5204 return main.TRUE
5205 except pexpect.TIMEOUT:
5206 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005207 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005208 except pexpect.EOF:
5209 main.log.error( self.name + ": EOF exception found" )
5210 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005211 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005212 except Exception:
5213 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005214 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005215
5216 def getGraphDict( self, timeout=60, includeHost=False ):
5217 """
5218 Return a dictionary which describes the latest network topology data as a
5219 graph.
5220 An example of the dictionary:
5221 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5222 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5223 Each vertex should at least have an 'edges' attribute which describes the
5224 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005225 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005226 list of attributes.
5227 An example of the edges dictionary:
5228 'edges': { vertex2: { 'port': ..., 'weight': ... },
5229 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005230 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005231 in topology data.
5232 """
5233 graphDict = {}
5234 try:
5235 links = self.links()
5236 links = json.loads( links )
5237 devices = self.devices()
5238 devices = json.loads( devices )
5239 idToDevice = {}
5240 for device in devices:
5241 idToDevice[ device[ 'id' ] ] = device
5242 if includeHost:
5243 hosts = self.hosts()
5244 # FIXME: support 'includeHost' argument
5245 for link in links:
5246 nodeA = link[ 'src' ][ 'device' ]
5247 nodeB = link[ 'dst' ][ 'device' ]
5248 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005249 if nodeA not in graphDict.keys():
5250 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005251 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005252 'type': idToDevice[ nodeA ][ 'type' ],
5253 'available': idToDevice[ nodeA ][ 'available' ],
5254 'role': idToDevice[ nodeA ][ 'role' ],
5255 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5256 'hw': idToDevice[ nodeA ][ 'hw' ],
5257 'sw': idToDevice[ nodeA ][ 'sw' ],
5258 'serial': idToDevice[ nodeA ][ 'serial' ],
5259 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005260 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005261 else:
5262 # Assert nodeB is not connected to any current links of nodeA
5263 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005264 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5265 'type': link[ 'type' ],
5266 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005267 return graphDict
5268 except ( TypeError, ValueError ):
5269 main.log.exception( self.name + ": Object not as expected" )
5270 return None
5271 except KeyError:
5272 main.log.exception( self.name + ": KeyError exception found" )
5273 return None
5274 except AssertionError:
5275 main.log.exception( self.name + ": AssertionError exception found" )
5276 return None
5277 except pexpect.EOF:
5278 main.log.error( self.name + ": EOF exception found" )
5279 main.log.error( self.name + ": " + self.handle.before )
5280 return None
5281 except Exception:
5282 main.log.exception( self.name + ": Uncaught exception!" )
5283 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005284
5285 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005286 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005287 Send command to check intent-perf summary
5288 Returns: dictionary for intent-perf summary
5289 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005290 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005291 cmd = "intent-perf -s"
5292 respDic = {}
5293 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005294 assert resp is not None, "Error in sendline"
5295 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005296 try:
5297 # Generate the dictionary to return
5298 for l in resp.split( "\n" ):
5299 # Delete any white space in line
5300 temp = re.sub( r'\s+', '', l )
5301 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005302 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005303
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005304 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005305 main.log.exception( self.name + ": Object not as expected" )
5306 return None
5307 except KeyError:
5308 main.log.exception( self.name + ": KeyError exception found" )
5309 return None
5310 except AssertionError:
5311 main.log.exception( self.name + ": AssertionError exception found" )
5312 return None
5313 except pexpect.EOF:
5314 main.log.error( self.name + ": EOF exception found" )
5315 main.log.error( self.name + ": " + self.handle.before )
5316 return None
5317 except Exception:
5318 main.log.exception( self.name + ": Uncaught exception!" )
5319 return None
5320 return respDic
5321
Chiyu Chengec63bde2016-11-17 18:11:36 -08005322 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005323 """
5324 Searches the latest ONOS log file for the given search term and
5325 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005326
chengchiyu08303a02016-09-08 17:40:26 -07005327 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005328 searchTerm:
5329 The string to grep from the ONOS log.
5330 startLine:
5331 The term that decides which line is the start to search the searchTerm in
5332 the karaf log. For now, startTerm only works in 'first' mode.
5333 logNum:
5334 In some extreme cases, one karaf log is not big enough to contain all the
5335 information.Because of this, search mutiply logs is necessary to capture
5336 the right result. logNum is the number of karaf logs that we need to search
5337 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005338 mode:
5339 all: return all the strings that contain the search term
5340 last: return the last string that contains the search term
5341 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005342 num: return the number of times that the searchTerm appears in the log
5343 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005344 """
5345 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005346 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005347 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005348 logPath = '/opt/onos/log/karaf.log.'
5349 logPaths = '/opt/onos/log/karaf.log'
5350 for i in range( 1, logNum ):
5351 logPaths = logPath + str( i ) + " " + logPaths
5352 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005353 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005354 # 100000000 is just a extreme large number to make sure this function can
5355 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005356 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005357 if mode == 'all':
5358 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005359 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005360 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005361 elif mode == 'first':
5362 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5363 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005364 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005365 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005366 return num
You Wang6d301d42017-04-21 10:49:33 -07005367 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005368 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005369 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005370 else:
5371 main.log.error( self.name + " unsupported mode" )
5372 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005373 before = self.sendline( cmd )
5374 before = before.splitlines()
5375 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005376 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005377 return returnLines
5378 except AssertionError:
5379 main.log.error( self.name + " searchTerm is not string type" )
5380 return None
5381 except pexpect.EOF:
5382 main.log.error( self.name + ": EOF exception found" )
5383 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005384 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005385 except pexpect.TIMEOUT:
5386 main.log.error( self.name + ": TIMEOUT exception found" )
5387 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005388 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005389 except Exception:
5390 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005391 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005392
5393 def vplsShow( self, jsonFormat=True ):
5394 """
5395 Description: Returns result of onos:vpls show, which should list the
5396 configured VPLS networks and the assigned interfaces.
5397 Optional:
5398 * jsonFormat: enable json formatting of output
5399 Returns:
5400 The output of the command or None on error.
5401 """
5402 try:
5403 cmdStr = "vpls show"
5404 if jsonFormat:
5405 raise NotImplementedError
5406 cmdStr += " -j"
5407 handle = self.sendline( cmdStr )
5408 assert handle is not None, "Error in sendline"
5409 assert "Command not found:" not in handle, handle
5410 return handle
5411 except AssertionError:
5412 main.log.exception( "" )
5413 return None
5414 except TypeError:
5415 main.log.exception( self.name + ": Object not as expected" )
5416 return None
5417 except pexpect.EOF:
5418 main.log.error( self.name + ": EOF exception found" )
5419 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005420 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005421 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005422 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005423 return None
5424 except Exception:
5425 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005426 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005427
5428 def parseVplsShow( self ):
5429 """
5430 Parse the cli output of 'vpls show' into json output. This is required
5431 as there is currently no json output available.
5432 """
5433 try:
5434 output = []
5435 raw = self.vplsShow( jsonFormat=False )
5436 namePat = "VPLS name: (?P<name>\w+)"
5437 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5438 encapPat = "Encapsulation: (?P<encap>\w+)"
5439 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5440 mIter = re.finditer( pattern, raw )
5441 for match in mIter:
5442 item = {}
5443 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005444 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005445 if ifaces == [ "" ]:
5446 ifaces = []
5447 item[ 'interfaces' ] = ifaces
5448 encap = match.group( 'encap' )
5449 if encap != 'NONE':
5450 item[ 'encapsulation' ] = encap.lower()
5451 output.append( item )
5452 return output
5453 except Exception:
5454 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005455 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005456
5457 def vplsList( self, jsonFormat=True ):
5458 """
5459 Description: Returns result of onos:vpls list, which should list the
5460 configured VPLS networks.
5461 Optional:
5462 * jsonFormat: enable json formatting of output
5463 """
5464 try:
5465 cmdStr = "vpls list"
5466 if jsonFormat:
5467 raise NotImplementedError
5468 cmdStr += " -j"
5469 handle = self.sendline( cmdStr )
5470 assert handle is not None, "Error in sendline"
5471 assert "Command not found:" not in handle, handle
5472 return handle
5473 except AssertionError:
5474 main.log.exception( "" )
5475 return None
5476 except TypeError:
5477 main.log.exception( self.name + ": Object not as expected" )
5478 return None
5479 except pexpect.EOF:
5480 main.log.error( self.name + ": EOF exception found" )
5481 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005482 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005483 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005484 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005485 return None
5486 except Exception:
5487 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005488 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005489
5490 def vplsCreate( self, network ):
5491 """
5492 CLI command to create a new VPLS network.
5493 Required arguments:
5494 network - String name of the network to create.
5495 returns:
5496 main.TRUE on success and main.FALSE on failure
5497 """
5498 try:
5499 network = str( network )
5500 cmdStr = "vpls create "
5501 cmdStr += network
5502 output = self.sendline( cmdStr )
5503 assert output is not None, "Error in sendline"
5504 assert "Command not found:" not in output, output
5505 assert "Error executing command" not in output, output
5506 assert "VPLS already exists:" not in output, output
5507 return main.TRUE
5508 except AssertionError:
5509 main.log.exception( "" )
5510 return main.FALSE
5511 except TypeError:
5512 main.log.exception( self.name + ": Object not as expected" )
5513 return main.FALSE
5514 except pexpect.EOF:
5515 main.log.error( self.name + ": EOF exception found" )
5516 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005517 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005518 except Exception:
5519 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005520 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005521
5522 def vplsDelete( self, network ):
5523 """
5524 CLI command to delete a VPLS network.
5525 Required arguments:
5526 network - Name of the network to delete.
5527 returns:
5528 main.TRUE on success and main.FALSE on failure
5529 """
5530 try:
5531 network = str( network )
5532 cmdStr = "vpls delete "
5533 cmdStr += network
5534 output = self.sendline( cmdStr )
5535 assert output is not None, "Error in sendline"
5536 assert "Command not found:" not in output, output
5537 assert "Error executing command" not in output, output
5538 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005539 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005540 return main.TRUE
5541 except AssertionError:
5542 main.log.exception( "" )
5543 return main.FALSE
5544 except TypeError:
5545 main.log.exception( self.name + ": Object not as expected" )
5546 return main.FALSE
5547 except pexpect.EOF:
5548 main.log.error( self.name + ": EOF exception found" )
5549 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005550 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005551 except Exception:
5552 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005553 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005554
5555 def vplsAddIface( self, network, iface ):
5556 """
5557 CLI command to add an interface to a VPLS network.
5558 Required arguments:
5559 network - Name of the network to add the interface to.
5560 iface - The ONOS name for an interface.
5561 returns:
5562 main.TRUE on success and main.FALSE on failure
5563 """
5564 try:
5565 network = str( network )
5566 iface = str( iface )
5567 cmdStr = "vpls add-if "
5568 cmdStr += network + " " + iface
5569 output = self.sendline( cmdStr )
5570 assert output is not None, "Error in sendline"
5571 assert "Command not found:" not in output, output
5572 assert "Error executing command" not in output, output
5573 assert "already associated to network" not in output, output
5574 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005575 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005576 return main.TRUE
5577 except AssertionError:
5578 main.log.exception( "" )
5579 return main.FALSE
5580 except TypeError:
5581 main.log.exception( self.name + ": Object not as expected" )
5582 return main.FALSE
5583 except pexpect.EOF:
5584 main.log.error( self.name + ": EOF exception found" )
5585 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005586 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005587 except Exception:
5588 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005589 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005590
5591 def vplsRemIface( self, network, iface ):
5592 """
5593 CLI command to remove an interface from a VPLS network.
5594 Required arguments:
5595 network - Name of the network to remove the interface from.
5596 iface - Name of the interface to remove.
5597 returns:
5598 main.TRUE on success and main.FALSE on failure
5599 """
5600 try:
5601 iface = str( iface )
5602 cmdStr = "vpls rem-if "
5603 cmdStr += network + " " + iface
5604 output = self.sendline( cmdStr )
5605 assert output is not None, "Error in sendline"
5606 assert "Command not found:" not in output, output
5607 assert "Error executing command" not in output, output
5608 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005609 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005610 return main.TRUE
5611 except AssertionError:
5612 main.log.exception( "" )
5613 return main.FALSE
5614 except TypeError:
5615 main.log.exception( self.name + ": Object not as expected" )
5616 return main.FALSE
5617 except pexpect.EOF:
5618 main.log.error( self.name + ": EOF exception found" )
5619 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005620 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005621 except Exception:
5622 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005623 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005624
5625 def vplsClean( self ):
5626 """
5627 Description: Clears the VPLS app configuration.
5628 Returns: main.TRUE on success and main.FALSE on failure
5629 """
5630 try:
5631 cmdStr = "vpls clean"
5632 handle = self.sendline( cmdStr )
5633 assert handle is not None, "Error in sendline"
5634 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005635 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005636 return handle
5637 except AssertionError:
5638 main.log.exception( "" )
5639 return main.FALSE
5640 except TypeError:
5641 main.log.exception( self.name + ": Object not as expected" )
5642 return main.FALSE
5643 except pexpect.EOF:
5644 main.log.error( self.name + ": EOF exception found" )
5645 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005646 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005647 except Exception:
5648 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005649 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005650
5651 def vplsSetEncap( self, network, encapType ):
5652 """
5653 CLI command to add an interface to a VPLS network.
5654 Required arguments:
5655 network - Name of the network to create.
5656 encapType - Type of encapsulation.
5657 returns:
5658 main.TRUE on success and main.FALSE on failure
5659 """
5660 try:
5661 network = str( network )
5662 encapType = str( encapType ).upper()
5663 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5664 cmdStr = "vpls set-encap "
5665 cmdStr += network + " " + encapType
5666 output = self.sendline( cmdStr )
5667 assert output is not None, "Error in sendline"
5668 assert "Command not found:" not in output, output
5669 assert "Error executing command" not in output, output
5670 assert "already associated to network" not in output, output
5671 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005672 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005673 return main.TRUE
5674 except AssertionError:
5675 main.log.exception( "" )
5676 return main.FALSE
5677 except TypeError:
5678 main.log.exception( self.name + ": Object not as expected" )
5679 return main.FALSE
5680 except pexpect.EOF:
5681 main.log.error( self.name + ": EOF exception found" )
5682 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005683 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005684 except Exception:
5685 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005686 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005687
5688 def interfaces( self, jsonFormat=True ):
5689 """
5690 Description: Returns result of interfaces command.
5691 Optional:
5692 * jsonFormat: enable json formatting of output
5693 Returns:
5694 The output of the command or None on error.
5695 """
5696 try:
5697 cmdStr = "interfaces"
5698 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005699 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005700 cmdStr += " -j"
5701 handle = self.sendline( cmdStr )
5702 assert handle is not None, "Error in sendline"
5703 assert "Command not found:" not in handle, handle
5704 return handle
5705 except AssertionError:
5706 main.log.exception( "" )
5707 return None
5708 except TypeError:
5709 main.log.exception( self.name + ": Object not as expected" )
5710 return None
5711 except pexpect.EOF:
5712 main.log.error( self.name + ": EOF exception found" )
5713 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005714 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005715 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005716 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005717 return None
5718 except Exception:
5719 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005720 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005721
5722 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005723 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005724 Get the timestamp of searchTerm from karaf log.
5725
5726 Arguments:
5727 splitTerm_before and splitTerm_after:
5728
5729 The terms that split the string that contains the timeStamp of
5730 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5731 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5732 and the splitTerm_after is "x"
5733
5734 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005735 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005736 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005737 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005738 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005739 return main.ERROR
5740 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005741 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005742 main.log.warn( "Captured timestamp string is empty" )
5743 return main.ERROR
5744 lines = lines[ 0 ]
5745 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005746 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005747 # get the target value
5748 line = lines.split( splitTerm_before )
5749 key = line[ 1 ].split( splitTerm_after )
5750 return int( key[ 0 ] )
5751 except IndexError:
5752 main.log.warn( "Index Error!" )
5753 return main.ERROR
5754 except AssertionError:
5755 main.log.warn( "Search Term Not Found " )
5756 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005757
5758 def workQueueAdd( self, queueName, value ):
5759 """
5760 CLI command to add a string to the specified Work Queue.
5761 This function uses the distributed primitives test app, which
5762 gives some cli access to distributed primitives for testing
5763 purposes only.
5764
5765 Required arguments:
5766 queueName - The name of the queue to add to
5767 value - The value to add to the queue
5768 returns:
5769 main.TRUE on success, main.FALSE on failure and
5770 main.ERROR on error.
5771 """
5772 try:
5773 queueName = str( queueName )
5774 value = str( value )
5775 prefix = "work-queue-test"
5776 operation = "add"
5777 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5778 output = self.distPrimitivesSend( cmdStr )
5779 if "Invalid operation name" in output:
5780 main.log.warn( output )
5781 return main.ERROR
5782 elif "Done" in output:
5783 return main.TRUE
5784 except TypeError:
5785 main.log.exception( self.name + ": Object not as expected" )
5786 return main.ERROR
5787 except Exception:
5788 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005789 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005790
5791 def workQueueAddMultiple( self, queueName, value1, value2 ):
5792 """
5793 CLI command to add two strings to the specified Work Queue.
5794 This function uses the distributed primitives test app, which
5795 gives some cli access to distributed primitives for testing
5796 purposes only.
5797
5798 Required arguments:
5799 queueName - The name of the queue to add to
5800 value1 - The first value to add to the queue
5801 value2 - The second value to add to the queue
5802 returns:
5803 main.TRUE on success, main.FALSE on failure and
5804 main.ERROR on error.
5805 """
5806 try:
5807 queueName = str( queueName )
5808 value1 = str( value1 )
5809 value2 = str( value2 )
5810 prefix = "work-queue-test"
5811 operation = "addMultiple"
5812 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5813 output = self.distPrimitivesSend( cmdStr )
5814 if "Invalid operation name" in output:
5815 main.log.warn( output )
5816 return main.ERROR
5817 elif "Done" in output:
5818 return main.TRUE
5819 except TypeError:
5820 main.log.exception( self.name + ": Object not as expected" )
5821 return main.ERROR
5822 except Exception:
5823 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005824 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005825
5826 def workQueueTakeAndComplete( self, queueName, number=1 ):
5827 """
5828 CLI command to take a value from the specified Work Queue and compelte it.
5829 This function uses the distributed primitives test app, which
5830 gives some cli access to distributed primitives for testing
5831 purposes only.
5832
5833 Required arguments:
5834 queueName - The name of the queue to add to
5835 number - The number of items to take and complete
5836 returns:
5837 main.TRUE on success, main.FALSE on failure and
5838 main.ERROR on error.
5839 """
5840 try:
5841 queueName = str( queueName )
5842 number = str( int( number ) )
5843 prefix = "work-queue-test"
5844 operation = "takeAndComplete"
5845 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5846 output = self.distPrimitivesSend( cmdStr )
5847 if "Invalid operation name" in output:
5848 main.log.warn( output )
5849 return main.ERROR
5850 elif "Done" in output:
5851 return main.TRUE
5852 except TypeError:
5853 main.log.exception( self.name + ": Object not as expected" )
5854 return main.ERROR
5855 except Exception:
5856 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005857 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005858
5859 def workQueueDestroy( self, queueName ):
5860 """
5861 CLI command to destroy the specified Work Queue.
5862 This function uses the distributed primitives test app, which
5863 gives some cli access to distributed primitives for testing
5864 purposes only.
5865
5866 Required arguments:
5867 queueName - The name of the queue to add to
5868 returns:
5869 main.TRUE on success, main.FALSE on failure and
5870 main.ERROR on error.
5871 """
5872 try:
5873 queueName = str( queueName )
5874 prefix = "work-queue-test"
5875 operation = "destroy"
5876 cmdStr = " ".join( [ prefix, queueName, operation ] )
5877 output = self.distPrimitivesSend( cmdStr )
5878 if "Invalid operation name" in output:
5879 main.log.warn( output )
5880 return main.ERROR
5881 return main.TRUE
5882 except TypeError:
5883 main.log.exception( self.name + ": Object not as expected" )
5884 return main.ERROR
5885 except Exception:
5886 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005887 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005888
5889 def workQueueTotalPending( self, queueName ):
5890 """
5891 CLI command to get the Total Pending items of the specified Work Queue.
5892 This function uses the distributed primitives test app, which
5893 gives some cli access to distributed primitives for testing
5894 purposes only.
5895
5896 Required arguments:
5897 queueName - The name of the queue to add to
5898 returns:
5899 The number of Pending items in the specified work queue or
5900 None on error
5901 """
5902 try:
5903 queueName = str( queueName )
5904 prefix = "work-queue-test"
5905 operation = "totalPending"
5906 cmdStr = " ".join( [ prefix, queueName, operation ] )
5907 output = self.distPrimitivesSend( cmdStr )
5908 pattern = r'\d+'
5909 if "Invalid operation name" in output:
5910 main.log.warn( output )
5911 return None
5912 else:
5913 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005914 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005915 except ( AttributeError, TypeError ):
5916 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5917 return None
5918 except Exception:
5919 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005920 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005921
5922 def workQueueTotalCompleted( self, queueName ):
5923 """
5924 CLI command to get the Total Completed items of the specified Work Queue.
5925 This function uses the distributed primitives test app, which
5926 gives some cli access to distributed primitives for testing
5927 purposes only.
5928
5929 Required arguments:
5930 queueName - The name of the queue to add to
5931 returns:
5932 The number of complete items in the specified work queue or
5933 None on error
5934 """
5935 try:
5936 queueName = str( queueName )
5937 prefix = "work-queue-test"
5938 operation = "totalCompleted"
5939 cmdStr = " ".join( [ prefix, queueName, operation ] )
5940 output = self.distPrimitivesSend( cmdStr )
5941 pattern = r'\d+'
5942 if "Invalid operation name" in output:
5943 main.log.warn( output )
5944 return None
5945 else:
5946 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005947 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005948 except ( AttributeError, TypeError ):
5949 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5950 return None
5951 except Exception:
5952 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005953 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005954
5955 def workQueueTotalInProgress( self, queueName ):
5956 """
5957 CLI command to get the Total In Progress items of the specified Work Queue.
5958 This function uses the distributed primitives test app, which
5959 gives some cli access to distributed primitives for testing
5960 purposes only.
5961
5962 Required arguments:
5963 queueName - The name of the queue to add to
5964 returns:
5965 The number of In Progress items in the specified work queue or
5966 None on error
5967 """
5968 try:
5969 queueName = str( queueName )
5970 prefix = "work-queue-test"
5971 operation = "totalInProgress"
5972 cmdStr = " ".join( [ prefix, queueName, operation ] )
5973 output = self.distPrimitivesSend( cmdStr )
5974 pattern = r'\d+'
5975 if "Invalid operation name" in output:
5976 main.log.warn( output )
5977 return None
5978 else:
5979 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005980 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005981 except ( AttributeError, TypeError ):
5982 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5983 return None
5984 except Exception:
5985 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005986 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005987
5988 def events( self, args='-a' ):
5989 """
5990 Description: Returns events -a command output
5991 Optional:
5992 add other arguments
5993 """
5994 try:
5995 cmdStr = "events"
5996 if args:
5997 cmdStr += " " + args
5998 handle = self.sendline( cmdStr )
5999 assert handle is not None, "Error in sendline"
6000 assert "Command not found:" not in handle, handle
6001 return handle
6002 except AssertionError:
6003 main.log.exception( "" )
6004 return None
6005 except TypeError:
6006 main.log.exception( self.name + ": Object not as expected" )
6007 return None
6008 except pexpect.EOF:
6009 main.log.error( self.name + ": EOF exception found" )
6010 main.log.error( self.name + ": " + self.handle.before )
6011 main.cleanAndExit()
6012 except Exception:
6013 main.log.exception( self.name + ": Uncaught exception!" )
6014 main.cleanAndExit()
6015
6016 def getMaster( self, deviceID ):
6017 """
6018 Description: Obtains current master using "roles" command for a specific deviceID
6019 """
6020 try:
6021 return str( self.getRole( deviceID )[ 'master' ] )
6022 except AssertionError:
6023 main.log.exception( "" )
6024 return None
6025 except TypeError:
6026 main.log.exception( self.name + ": Object not as expected" )
6027 return None
6028 except pexpect.EOF:
6029 main.log.error( self.name + ": EOF exception found" )
6030 main.log.error( self.name + ": " + self.handle.before )
6031 main.cleanAndExit()
6032 except Exception:
6033 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006034 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006035
6036 def issu( self ):
6037 """
6038 Short summary of In-Service Software Upgrade status
6039
6040 Returns the output of the cli command or None on Error
6041 """
6042 try:
6043 cmdStr = "issu"
6044 handle = self.sendline( cmdStr )
6045 assert handle is not None, "Error in sendline"
6046 assert "Command not found:" not in handle, handle
6047 assert "Unsupported command:" not in handle, handle
6048 return handle
6049 except AssertionError:
6050 main.log.exception( "" )
6051 return None
6052 except TypeError:
6053 main.log.exception( self.name + ": Object not as expected" )
6054 return None
6055 except pexpect.EOF:
6056 main.log.error( self.name + ": EOF exception found" )
6057 main.log.error( self.name + ": " + self.handle.before )
6058 main.cleanAndExit()
6059 except Exception:
6060 main.log.exception( self.name + ": Uncaught exception!" )
6061 main.cleanAndExit()
6062
6063 def issuInit( self ):
6064 """
6065 Initiates an In-Service Software Upgrade
6066
6067 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6068 """
6069 try:
6070 cmdStr = "issu init"
6071 handle = self.sendline( cmdStr )
6072 assert handle is not None, "Error in sendline"
6073 assert "Command not found:" not in handle, handle
6074 assert "Unsupported command:" not in handle, handle
6075 if "Initialized" in handle:
6076 return main.TRUE
6077 else:
6078 return main.FALSE
6079 except AssertionError:
6080 main.log.exception( "" )
6081 return main.ERROR
6082 except TypeError:
6083 main.log.exception( self.name + ": Object not as expected" )
6084 return main.ERROR
6085 except pexpect.EOF:
6086 main.log.error( self.name + ": EOF exception found" )
6087 main.log.error( self.name + ": " + self.handle.before )
6088 main.cleanAndExit()
6089 except Exception:
6090 main.log.exception( self.name + ": Uncaught exception!" )
6091 main.cleanAndExit()
6092
6093 def issuUpgrade( self ):
6094 """
6095 Transitions stores to upgraded nodes
6096
6097 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6098 """
6099 try:
6100 cmdStr = "issu upgrade"
6101 handle = self.sendline( cmdStr )
6102 assert handle is not None, "Error in sendline"
6103 assert "Command not found:" not in handle, handle
6104 assert "Unsupported command:" not in handle, handle
6105 if "Upgraded" in handle:
6106 return main.TRUE
6107 else:
6108 return main.FALSE
6109 except AssertionError:
6110 main.log.exception( "" )
6111 return main.ERROR
6112 except TypeError:
6113 main.log.exception( self.name + ": Object not as expected" )
6114 return main.ERROR
6115 except pexpect.EOF:
6116 main.log.error( self.name + ": EOF exception found" )
6117 main.log.error( self.name + ": " + self.handle.before )
6118 main.cleanAndExit()
6119 except Exception:
6120 main.log.exception( self.name + ": Uncaught exception!" )
6121 main.cleanAndExit()
6122
6123 def issuCommit( self ):
6124 """
6125 Finalizes an In-Service Software Upgrade
6126
6127 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6128 """
6129 try:
6130 cmdStr = "issu commit"
6131 handle = self.sendline( cmdStr )
6132 assert handle is not None, "Error in sendline"
6133 assert "Command not found:" not in handle, handle
6134 assert "Unsupported command:" not in handle, handle
6135 # TODO: Check the version returned by this command
6136 if "Committed version" in handle:
6137 return main.TRUE
6138 else:
6139 return main.FALSE
6140 except AssertionError:
6141 main.log.exception( "" )
6142 return main.ERROR
6143 except TypeError:
6144 main.log.exception( self.name + ": Object not as expected" )
6145 return main.ERROR
6146 except pexpect.EOF:
6147 main.log.error( self.name + ": EOF exception found" )
6148 main.log.error( self.name + ": " + self.handle.before )
6149 main.cleanAndExit()
6150 except Exception:
6151 main.log.exception( self.name + ": Uncaught exception!" )
6152 main.cleanAndExit()
6153
6154 def issuRollback( self ):
6155 """
6156 Rolls back an In-Service Software Upgrade
6157
6158 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6159 """
6160 try:
6161 cmdStr = "issu rollback"
6162 handle = self.sendline( cmdStr )
6163 assert handle is not None, "Error in sendline"
6164 assert "Command not found:" not in handle, handle
6165 assert "Unsupported command:" not in handle, handle
6166 # TODO: Check the version returned by this command
6167 if "Rolled back to version" in handle:
6168 return main.TRUE
6169 else:
6170 return main.FALSE
6171 except AssertionError:
6172 main.log.exception( "" )
6173 return main.ERROR
6174 except TypeError:
6175 main.log.exception( self.name + ": Object not as expected" )
6176 return main.ERROR
6177 except pexpect.EOF:
6178 main.log.error( self.name + ": EOF exception found" )
6179 main.log.error( self.name + ": " + self.handle.before )
6180 main.cleanAndExit()
6181 except Exception:
6182 main.log.exception( self.name + ": Uncaught exception!" )
6183 main.cleanAndExit()
6184
6185 def issuReset( self ):
6186 """
6187 Resets the In-Service Software Upgrade status after a rollback
6188
6189 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6190 """
6191 try:
6192 cmdStr = "issu reset"
6193 handle = self.sendline( cmdStr )
6194 assert handle is not None, "Error in sendline"
6195 assert "Command not found:" not in handle, handle
6196 assert "Unsupported command:" not in handle, handle
6197 # TODO: Check the version returned by this command
6198 if "Reset version" in handle:
6199 return main.TRUE
6200 else:
6201 return main.FALSE
6202 except AssertionError:
6203 main.log.exception( "" )
6204 return main.ERROR
6205 except TypeError:
6206 main.log.exception( self.name + ": Object not as expected" )
6207 return main.ERROR
6208 except pexpect.EOF:
6209 main.log.error( self.name + ": EOF exception found" )
6210 main.log.error( self.name + ": " + self.handle.before )
6211 main.cleanAndExit()
6212 except Exception:
6213 main.log.exception( self.name + ": Uncaught exception!" )
6214 main.cleanAndExit()
6215
6216 def issuStatus( self ):
6217 """
6218 Status of an In-Service Software Upgrade
6219
6220 Returns the output of the cli command or None on Error
6221 """
6222 try:
6223 cmdStr = "issu status"
6224 handle = self.sendline( cmdStr )
6225 assert handle is not None, "Error in sendline"
6226 assert "Command not found:" not in handle, handle
6227 assert "Unsupported command:" not in handle, handle
6228 return handle
6229 except AssertionError:
6230 main.log.exception( "" )
6231 return None
6232 except TypeError:
6233 main.log.exception( self.name + ": Object not as expected" )
6234 return None
6235 except pexpect.EOF:
6236 main.log.error( self.name + ": EOF exception found" )
6237 main.log.error( self.name + ": " + self.handle.before )
6238 main.cleanAndExit()
6239 except Exception:
6240 main.log.exception( self.name + ": Uncaught exception!" )
6241 main.cleanAndExit()
6242
6243 def issuVersion( self ):
6244 """
6245 Get the version of an In-Service Software Upgrade
6246
6247 Returns the output of the cli command or None on Error
6248 """
6249 try:
6250 cmdStr = "issu version"
6251 handle = self.sendline( cmdStr )
6252 assert handle is not None, "Error in sendline"
6253 assert "Command not found:" not in handle, handle
6254 assert "Unsupported command:" not in handle, handle
6255 return handle
6256 except AssertionError:
6257 main.log.exception( "" )
6258 return None
6259 except TypeError:
6260 main.log.exception( self.name + ": Object not as expected" )
6261 return None
6262 except pexpect.EOF:
6263 main.log.error( self.name + ": EOF exception found" )
6264 main.log.error( self.name + ": " + self.handle.before )
6265 main.cleanAndExit()
6266 except Exception:
6267 main.log.exception( self.name + ": Uncaught exception!" )
6268 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006269
6270 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6271 """
6272 Create a multicast route by calling 'mcast-join' command
6273 sIP: source IP of the multicast route
6274 groupIP: group IP of the multicast route
6275 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6276 dPorts: a list of destination ports of the multicast route
6277 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6278 """
6279 try:
6280 cmdStr = "mcast-join"
6281 cmdStr += " " + str( sIP )
6282 cmdStr += " " + str( groupIP )
6283 cmdStr += " " + str( sPort )
6284 assert isinstance( dPorts, list )
6285 for dPort in dPorts:
6286 cmdStr += " " + str( dPort )
6287 handle = self.sendline( cmdStr )
6288 assert handle is not None, "Error in sendline"
6289 assert "Command not found:" not in handle, handle
6290 assert "Unsupported command:" not in handle, handle
6291 assert "Error executing command" not in handle, handle
6292 if "Added the mcast route" in handle:
6293 return main.TRUE
6294 else:
6295 return main.FALSE
6296 except AssertionError:
6297 main.log.exception( "" )
6298 return None
6299 except TypeError:
6300 main.log.exception( self.name + ": Object not as expected" )
6301 return None
6302 except pexpect.EOF:
6303 main.log.error( self.name + ": EOF exception found" )
6304 main.log.error( self.name + ": " + self.handle.before )
6305 main.cleanAndExit()
6306 except Exception:
6307 main.log.exception( self.name + ": Uncaught exception!" )
6308 main.cleanAndExit()
6309
6310 def mcastDelete( self, sIP, groupIP, dPorts ):
6311 """
6312 Delete a multicast route by calling 'mcast-delete' command
6313 sIP: source IP of the multicast route
6314 groupIP: group IP of the multicast route
6315 dPorts: a list of destination ports of the multicast route
6316 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6317 """
6318 try:
6319 cmdStr = "mcast-delete"
6320 cmdStr += " " + str( sIP )
6321 cmdStr += " " + str( groupIP )
6322 assert isinstance( dPorts, list )
6323 for dPort in dPorts:
6324 cmdStr += " " + str( dPort )
6325 handle = self.sendline( cmdStr )
6326 assert handle is not None, "Error in sendline"
6327 assert "Command not found:" not in handle, handle
6328 assert "Unsupported command:" not in handle, handle
6329 assert "Error executing command" not in handle, handle
6330 if "Updated the mcast route" in handle:
6331 return main.TRUE
6332 else:
6333 return main.FALSE
6334 except AssertionError:
6335 main.log.exception( "" )
6336 return None
6337 except TypeError:
6338 main.log.exception( self.name + ": Object not as expected" )
6339 return None
6340 except pexpect.EOF:
6341 main.log.error( self.name + ": EOF exception found" )
6342 main.log.error( self.name + ": " + self.handle.before )
6343 main.cleanAndExit()
6344 except Exception:
6345 main.log.exception( self.name + ": Uncaught exception!" )
6346 main.cleanAndExit()
6347
6348 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6349 """
6350 Create a multicast route by calling 'mcast-host-join' command
6351 sAddr: we can provide * for ASM or a specific address for SSM
6352 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006353 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006354 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6355 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6356 """
6357 try:
6358 cmdStr = "mcast-host-join"
6359 cmdStr += " -sAddr " + str( sAddr )
6360 cmdStr += " -gAddr " + str( gAddr )
6361 assert isinstance( srcs, list )
6362 for src in srcs:
6363 cmdStr += " -srcs " + str( src )
6364 assert isinstance( sinks, list )
6365 for sink in sinks:
6366 cmdStr += " -sinks " + str( sink )
6367 handle = self.sendline( cmdStr )
6368 assert handle is not None, "Error in sendline"
6369 assert "Command not found:" not in handle, handle
6370 assert "Unsupported command:" not in handle, handle
6371 assert "Error executing command" not in handle, handle
6372 if "Added the mcast route" in handle:
6373 return main.TRUE
6374 else:
6375 return main.FALSE
6376 except AssertionError:
6377 main.log.exception( "" )
6378 return None
6379 except TypeError:
6380 main.log.exception( self.name + ": Object not as expected" )
6381 return None
6382 except pexpect.EOF:
6383 main.log.error( self.name + ": EOF exception found" )
6384 main.log.error( self.name + ": " + self.handle.before )
6385 main.cleanAndExit()
6386 except Exception:
6387 main.log.exception( self.name + ": Uncaught exception!" )
6388 main.cleanAndExit()
6389
6390 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6391 """
6392 Delete multicast sink(s) by calling 'mcast-host-delete' command
6393 sAddr: we can provide * for ASM or a specific address for SSM
6394 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006395 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006396 will delete the route if not specified
6397 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6398 """
6399 try:
6400 cmdStr = "mcast-host-delete"
6401 cmdStr += " -sAddr " + str( sAddr )
6402 cmdStr += " -gAddr " + str( gAddr )
6403 if host:
6404 cmdStr += " -h " + str( host )
6405 handle = self.sendline( cmdStr )
6406 assert handle is not None, "Error in sendline"
6407 assert "Command not found:" not in handle, handle
6408 assert "Unsupported command:" not in handle, handle
6409 assert "Error executing command" not in handle, handle
6410 if "Updated the mcast route" in handle:
6411 return main.TRUE
6412 elif "Deleted the mcast route" in handle:
6413 return main.TRUE
6414 else:
6415 return main.FALSE
6416 except AssertionError:
6417 main.log.exception( "" )
6418 return None
6419 except TypeError:
6420 main.log.exception( self.name + ": Object not as expected" )
6421 return None
6422 except pexpect.EOF:
6423 main.log.error( self.name + ": EOF exception found" )
6424 main.log.error( self.name + ": " + self.handle.before )
6425 main.cleanAndExit()
6426 except Exception:
6427 main.log.exception( self.name + ": Uncaught exception!" )
6428 main.cleanAndExit()
6429
You Wang547893e2018-05-08 13:34:59 -07006430 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6431 """
6432 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6433 sAddr: we can provide * for ASM or a specific address for SSM
6434 gAddr: specifies multicast group address
6435 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6436 will delete the route if not specified
6437 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6438 """
6439 try:
6440 cmdStr = "mcast-sink-delete"
6441 cmdStr += " -sAddr " + str( sAddr )
6442 cmdStr += " -gAddr " + str( gAddr )
6443 if sink:
6444 cmdStr += " -s " + str( sink )
6445 handle = self.sendline( cmdStr )
6446 assert handle is not None, "Error in sendline"
6447 assert "Command not found:" not in handle, handle
6448 assert "Unsupported command:" not in handle, handle
6449 assert "Error executing command" not in handle, handle
6450 if "Updated the mcast route" in handle:
6451 return main.TRUE
6452 elif "Deleted the mcast route" in handle:
6453 return main.TRUE
6454 else:
6455 return main.FALSE
6456 except AssertionError:
6457 main.log.exception( "" )
6458 return None
6459 except TypeError:
6460 main.log.exception( self.name + ": Object not as expected" )
6461 return None
6462 except pexpect.EOF:
6463 main.log.error( self.name + ": EOF exception found" )
6464 main.log.error( self.name + ": " + self.handle.before )
6465 main.cleanAndExit()
6466 except Exception:
6467 main.log.exception( self.name + ": Uncaught exception!" )
6468 main.cleanAndExit()
6469
You Wange24d6272018-03-27 21:18:50 -07006470 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6471 """
6472 Delete multicast src(s) by calling 'mcast-source-delete' command
6473 sAddr: we can provide * for ASM or a specific address for SSM
6474 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006475 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 -07006476 will delete the route if not specified
6477 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6478 """
6479 try:
6480 cmdStr = "mcast-source-delete"
6481 cmdStr += " -sAddr " + str( sAddr )
6482 cmdStr += " -gAddr " + str( gAddr )
6483 if srcs:
6484 assert isinstance( srcs, list )
6485 for src in srcs:
6486 cmdStr += " -src " + str( src )
6487 handle = self.sendline( cmdStr )
6488 assert handle is not None, "Error in sendline"
6489 assert "Command not found:" not in handle, handle
6490 assert "Unsupported command:" not in handle, handle
6491 assert "Error executing command" not in handle, handle
6492 if "Updated the mcast route" in handle:
6493 return main.TRUE
6494 elif "Deleted the mcast route" in handle:
6495 return main.TRUE
6496 else:
6497 return main.FALSE
6498 except AssertionError:
6499 main.log.exception( "" )
6500 return None
6501 except TypeError:
6502 main.log.exception( self.name + ": Object not as expected" )
6503 return None
6504 except pexpect.EOF:
6505 main.log.error( self.name + ": EOF exception found" )
6506 main.log.error( self.name + ": " + self.handle.before )
6507 main.cleanAndExit()
6508 except Exception:
6509 main.log.exception( self.name + ": Uncaught exception!" )
6510 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006511
6512 def netcfg( self, jsonFormat=True, args="" ):
6513 """
6514 Run netcfg cli command with given args
6515 """
6516 try:
6517 cmdStr = "netcfg"
6518 if jsonFormat:
6519 cmdStr = cmdStr + " -j"
6520 if args:
6521 cmdStr = cmdStr + " " + str( args )
6522 handle = self.sendline( cmdStr )
6523 assert handle is not None, "Error in sendline"
6524 assert "Command not found:" not in handle, handle
6525 assert "Unsupported command:" not in handle, handle
6526 assert "Error executing command" not in handle, handle
6527 return handle
6528 except AssertionError:
6529 main.log.exception( "" )
6530 return None
6531 except TypeError:
6532 main.log.exception( self.name + ": Object not as expected" )
6533 return None
6534 except pexpect.EOF:
6535 main.log.error( self.name + ": EOF exception found" )
6536 main.log.error( self.name + ": " + self.handle.before )
6537 main.cleanAndExit()
6538 except Exception:
6539 main.log.exception( self.name + ": Uncaught exception!" )
6540 main.cleanAndExit()
6541
You Wang0fa76e72018-05-18 11:33:25 -07006542 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006543 """
You Wang54b1d672018-06-11 16:44:13 -07006544 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006545 Options:
6546 sAddr: IP address of the source host
6547 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006548 ipv6: True if hosts are IPv6
6549 verbose: return verbose t3 output if True
6550 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006551 """
6552 try:
6553 # Collect information of both hosts from onos
6554 hosts = self.hosts()
6555 hosts = json.loads( hosts )
6556 sHost = None
6557 dHost = None
6558 for host in hosts:
6559 if sAddr in host[ "ipAddresses" ]:
6560 sHost = host
6561 elif dAddr in host[ "ipAddresses" ]:
6562 dHost = host
6563 if sHost and dHost:
6564 break
6565 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006566 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006567 if simple:
6568 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006569 cmdStr = "t3-troubleshoot-simple"
6570 if verbose:
6571 cmdStr += " -vv"
6572 if ipv6:
6573 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006574 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006575 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006576 else:
You Wang54b1d672018-06-11 16:44:13 -07006577 for location in sHost[ "locations" ]:
6578 cmdStr = "t3-troubleshoot"
6579 if verbose:
6580 cmdStr += " -vv"
6581 if ipv6:
6582 cmdStr += " -et ipv6"
6583 cmdStr += " -s " + str( sAddr )
6584 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6585 cmdStr += " -sm " + str( sHost[ "mac" ] )
6586 if sHost[ "vlan" ] != "None":
6587 cmdStr += " -vid " + sHost[ "vlan" ]
6588 cmdStr += " -d " + str( dAddr )
6589 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6590 netcfg = json.loads( netcfg )
6591 assert netcfg, "Failed to get netcfg"
6592 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6593 cmdList.append( cmdStr )
6594 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006595 except AssertionError:
6596 main.log.exception( "" )
6597 return None
6598 except ( KeyError, TypeError ):
6599 main.log.exception( self.name + ": Object not as expected" )
6600 return None
6601 except Exception:
6602 main.log.exception( self.name + ": Uncaught exception!" )
6603 main.cleanAndExit()
6604
6605 def t3( self, sAddr, dAddr, ipv6=False ):
6606 """
You Wang54b1d672018-06-11 16:44:13 -07006607 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006608 Options:
6609 sAddr: IP address of the source host
6610 dAddr: IP address of the destination host
6611 """
6612 try:
You Wang54b1d672018-06-11 16:44:13 -07006613 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6614 assert cmdList is not None, "composeT3Command returned None"
6615 t3Output = ""
6616 for cmdStr in cmdList:
6617 handle = self.sendline( cmdStr )
6618 assert handle is not None, "Error in sendline"
6619 assert "Command not found:" not in handle, handle
6620 assert "Unsupported command:" not in handle, handle
6621 assert "Error executing command" not in handle, handle
6622 assert "Tracing packet" in handle
6623 t3Output += handle
6624 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006625 except AssertionError:
6626 main.log.exception( "" )
6627 return None
6628 except pexpect.EOF:
6629 main.log.error( self.name + ": EOF exception found" )
6630 main.log.error( self.name + ": " + self.handle.before )
6631 main.cleanAndExit()
6632 except Exception:
6633 main.log.exception( self.name + ": Uncaught exception!" )
6634 main.cleanAndExit()