blob: 3841a76d9af35a343f92f27dcbc0b1f65f46f454 [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]
Jon Hall6c9e2da2018-11-06 12:01:23 -0800597 output = response.split( endStr.strip(), 1 )
598 else:
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800599 output = response.split( endStr.strip(), 1 )
600 if len( output ) < 2:
601 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hall0623dd42018-11-13 14:32:23 -0800602 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
Jon Halld5a94fb2018-11-13 14:32:23 -0800641 def lineCount( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True ):
642 """
643 A wrapper around sendline(). Will return the number of lines returned or None on error
644
645 Required Arguments:
646 cmdStr - String to send to the pexpect session
647
648 Optional Arguments:
649 showResponse - Defaults to False. If True will log the response.
650 debug - Defaults to False. If True, will enable debug logging.
651 timeout - Defaults to 10. Amount of time in seconds for a command to return
652 before a timeout.
653 noExit - Defaults to False. If True, will not exit TestON in the event of a
654 closed channel, but instead return None
655 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.
656
657 Warning: There are no sanity checking to commands sent using this method.
658
659 """
660 try:
661 numLines = self.sendline( cmdStr, showResponse, debug, timeout, noExit, relaxedRegex )
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800662 parsed = re.search( "(\d+)\s+(\d+)", numLines )
663 if not parsed:
664 main.log.error( "Warning, output of karaf's wc may have changed" )
665 return None
666 return parsed.group( 1 )
Jon Halld5a94fb2018-11-13 14:32:23 -0800667 except IndexError:
668 main.log.exception( self.name + ": Object not as expected" )
669 main.log.debug( "response: {}".format( repr( response ) ) )
670 return None
671 except TypeError:
672 main.log.exception( self.name + ": Object not as expected" )
673 return None
674 except Exception:
675 main.log.exception( self.name + ": Uncaught exception!" )
676 if noExit:
677 return None
678 else:
679 main.cleanAndExit()
680
kelvin8ec71442015-01-15 16:57:00 -0800681 # IMPORTANT NOTE:
682 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800683 # the cli command changing 'a:b' with 'aB'.
684 # Ex ) onos:topology > onosTopology
685 # onos:links > onosLinks
686 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800687
kelvin-onlabd3b64892015-01-20 13:26:24 -0800688 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800689 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400690 Adds a new cluster node by ID and address information.
691 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800692 * nodeId
693 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400694 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800695 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800696 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400697 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800698 cmdStr = "add-node " + str( nodeId ) + " " +\
699 str( ONOSIp ) + " " + str( tcpPort )
700 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700701 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800702 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800703 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700704 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800705 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800706 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400707 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800708 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400709 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800710 except AssertionError:
711 main.log.exception( "" )
712 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800713 except TypeError:
714 main.log.exception( self.name + ": Object not as expected" )
715 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400716 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800717 main.log.error( self.name + ": EOF exception found" )
718 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700719 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800720 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800721 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700722 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400723
kelvin-onlabd3b64892015-01-20 13:26:24 -0800724 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800725 """
andrewonlab86dc3082014-10-13 18:18:38 -0400726 Removes a cluster by ID
727 Issues command: 'remove-node [<node-id>]'
728 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800729 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800730 """
andrewonlab86dc3082014-10-13 18:18:38 -0400731 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400732
kelvin-onlabd3b64892015-01-20 13:26:24 -0800733 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700734 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700735 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800736 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700737 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700738 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700739 main.log.error( handle )
740 return main.FALSE
741 else:
742 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800743 except AssertionError:
744 main.log.exception( "" )
745 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800746 except TypeError:
747 main.log.exception( self.name + ": Object not as expected" )
748 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400749 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800750 main.log.error( self.name + ": EOF exception found" )
751 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700752 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800753 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800754 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700755 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400756
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700757 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800758 """
andrewonlab7c211572014-10-15 16:45:20 -0400759 List the nodes currently visible
760 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700761 Optional argument:
762 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800763 """
andrewonlab7c211572014-10-15 16:45:20 -0400764 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700765 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700766 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700767 cmdStr += " -j"
768 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700769 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800770 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700771 return output
Jon Hallc6793552016-01-19 14:18:37 -0800772 except AssertionError:
773 main.log.exception( "" )
774 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800775 except TypeError:
776 main.log.exception( self.name + ": Object not as expected" )
777 return None
andrewonlab7c211572014-10-15 16:45:20 -0400778 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800779 main.log.error( self.name + ": EOF exception found" )
780 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700781 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800782 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800783 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700784 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400785
kelvin8ec71442015-01-15 16:57:00 -0800786 def topology( self ):
787 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700788 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700789 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700790 Return:
791 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800792 """
andrewonlab95ce8322014-10-13 14:12:04 -0400793 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700794 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800795 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800796 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800797 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700798 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400799 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800800 except AssertionError:
801 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800802 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800803 except TypeError:
804 main.log.exception( self.name + ": Object not as expected" )
805 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400806 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800807 main.log.error( self.name + ": EOF exception found" )
808 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700809 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800810 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800811 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700812 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800813
jenkins7ead5a82015-03-13 10:28:21 -0700814 def deviceRemove( self, deviceId ):
815 """
816 Removes particular device from storage
817
818 TODO: refactor this function
819 """
820 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700821 cmdStr = "device-remove " + str( deviceId )
822 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800823 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800824 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700825 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700826 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700827 main.log.error( handle )
828 return main.FALSE
829 else:
830 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800831 except AssertionError:
832 main.log.exception( "" )
833 return None
jenkins7ead5a82015-03-13 10:28:21 -0700834 except TypeError:
835 main.log.exception( self.name + ": Object not as expected" )
836 return None
837 except pexpect.EOF:
838 main.log.error( self.name + ": EOF exception found" )
839 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700840 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700841 except Exception:
842 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700843 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700844
You Wang3b9689a2018-08-30 12:24:00 -0700845 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800846 """
Jon Hall7b02d952014-10-17 20:14:54 -0400847 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400848 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800849 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800850 """
andrewonlab86dc3082014-10-13 18:18:38 -0400851 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700852 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800853 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700854 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700855 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800856 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800857 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700858 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800859 except AssertionError:
860 main.log.exception( "" )
861 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800862 except TypeError:
863 main.log.exception( self.name + ": Object not as expected" )
864 return None
andrewonlab7c211572014-10-15 16:45:20 -0400865 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800866 main.log.error( self.name + ": EOF exception found" )
867 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700868 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800869 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800870 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700871 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400872
kelvin-onlabd3b64892015-01-20 13:26:24 -0800873 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800874 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800875 This balances the devices across all controllers
876 by issuing command: 'onos> onos:balance-masters'
877 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800878 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800879 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800880 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700881 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800882 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800883 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700884 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700885 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700886 main.log.error( handle )
887 return main.FALSE
888 else:
889 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800890 except AssertionError:
891 main.log.exception( "" )
892 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800893 except TypeError:
894 main.log.exception( self.name + ": Object not as expected" )
895 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800896 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800897 main.log.error( self.name + ": EOF exception found" )
898 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700899 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800900 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800901 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700902 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800903
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000904 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700905 """
906 Returns the output of the masters command.
907 Optional argument:
908 * jsonFormat - boolean indicating if you want output in json
909 """
910 try:
911 cmdStr = "onos:masters"
912 if jsonFormat:
913 cmdStr += " -j"
914 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700915 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800916 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700917 return output
Jon Hallc6793552016-01-19 14:18:37 -0800918 except AssertionError:
919 main.log.exception( "" )
920 return None
acsmars24950022015-07-30 18:00:43 -0700921 except TypeError:
922 main.log.exception( self.name + ": Object not as expected" )
923 return None
924 except pexpect.EOF:
925 main.log.error( self.name + ": EOF exception found" )
926 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700927 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700928 except Exception:
929 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700930 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700931
Jon Hallc6793552016-01-19 14:18:37 -0800932 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700933 """
934 Uses the master command to check that the devices' leadership
935 is evenly divided
936
937 Dependencies: checkMasters() and summary()
938
Jon Hall6509dbf2016-06-21 17:01:17 -0700939 Returns main.TRUE if the devices are balanced
940 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700941 Exits on Exception
942 Returns None on TypeError
943 """
944 try:
Jon Hallc6793552016-01-19 14:18:37 -0800945 summaryOutput = self.summary()
946 totalDevices = json.loads( summaryOutput )[ "devices" ]
947 except ( TypeError, ValueError ):
948 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
949 return None
950 try:
acsmars24950022015-07-30 18:00:43 -0700951 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800952 mastersOutput = self.checkMasters()
953 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700954 first = masters[ 0 ][ "size" ]
955 for master in masters:
956 totalOwnedDevices += master[ "size" ]
957 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
958 main.log.error( "Mastership not balanced" )
959 main.log.info( "\n" + self.checkMasters( False ) )
960 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700961 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700962 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700963 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800964 except ( TypeError, ValueError ):
965 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700966 return None
967 except pexpect.EOF:
968 main.log.error( self.name + ": EOF exception found" )
969 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700970 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700971 except Exception:
972 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700973 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700974
YPZhangfebf7302016-05-24 16:45:56 -0700975 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800976 """
Jon Halle8217482014-10-17 13:49:14 -0400977 Lists all core links
978 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800979 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800980 """
Jon Halle8217482014-10-17 13:49:14 -0400981 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700982 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800983 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700984 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700985 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800986 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800987 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700988 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800989 except AssertionError:
990 main.log.exception( "" )
991 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800992 except TypeError:
993 main.log.exception( self.name + ": Object not as expected" )
994 return None
Jon Halle8217482014-10-17 13:49:14 -0400995 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800996 main.log.error( self.name + ": EOF exception found" )
997 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700998 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800999 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001000 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001001 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001002
You Wang3b9689a2018-08-30 12:24:00 -07001003 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001004 """
Jon Halle8217482014-10-17 13:49:14 -04001005 Lists all ports
1006 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001007 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001008 """
Jon Halle8217482014-10-17 13:49:14 -04001009 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001010 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001011 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001012 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -07001013 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001014 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001015 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001016 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001017 except AssertionError:
1018 main.log.exception( "" )
1019 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001020 except TypeError:
1021 main.log.exception( self.name + ": Object not as expected" )
1022 return None
Jon Halle8217482014-10-17 13:49:14 -04001023 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001024 main.log.error( self.name + ": EOF exception found" )
1025 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001026 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001027 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001028 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001029 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001030
kelvin-onlabd3b64892015-01-20 13:26:24 -08001031 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001032 """
Jon Hall983a1702014-10-28 18:44:22 -04001033 Lists all devices and the controllers with roles assigned to them
1034 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001035 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001036 """
andrewonlab7c211572014-10-15 16:45:20 -04001037 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001038 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001039 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001040 cmdStr += " -j"
1041 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001042 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001043 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001044 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001045 except AssertionError:
1046 main.log.exception( "" )
1047 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001048 except TypeError:
1049 main.log.exception( self.name + ": Object not as expected" )
1050 return None
Jon Hall983a1702014-10-28 18:44:22 -04001051 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001052 main.log.error( self.name + ": EOF exception found" )
1053 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001054 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001055 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001056 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001057 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -04001058
kelvin-onlabd3b64892015-01-20 13:26:24 -08001059 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001060 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001061 Given the a string containing the json representation of the "roles"
1062 cli command and a partial or whole device id, returns a json object
1063 containing the roles output for the first device whose id contains
1064 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001065
1066 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001067 A dict of the role assignments for the given device or
1068 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001069 """
Jon Hall983a1702014-10-28 18:44:22 -04001070 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001071 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001072 return None
1073 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001074 rawRoles = self.roles()
1075 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001076 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001077 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001078 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001080 return device
1081 return None
Jon Hallc6793552016-01-19 14:18:37 -08001082 except ( TypeError, ValueError ):
1083 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001084 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001085 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001086 main.log.error( self.name + ": EOF exception found" )
1087 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001088 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001089 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001090 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001091 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001092
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001094 """
Jon Hall94fd0472014-12-08 11:52:42 -08001095 Iterates through each device and checks if there is a master assigned
1096 Returns: main.TRUE if each device has a master
1097 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001098 """
Jon Hall94fd0472014-12-08 11:52:42 -08001099 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001100 rawRoles = self.roles()
1101 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001102 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001103 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001104 # print device
1105 if device[ 'master' ] == "none":
1106 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001107 return main.FALSE
1108 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001109 except ( TypeError, ValueError ):
1110 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001111 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001112 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001113 main.log.error( self.name + ": EOF exception found" )
1114 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001115 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001116 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001117 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001118 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001119
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001121 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001122 Returns string of paths, and the cost.
1123 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001124 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001125 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001126 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1127 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001128 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001129 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001130 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001131 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001132 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001133 else:
kelvin8ec71442015-01-15 16:57:00 -08001134 path = handle.split( ";" )[ 0 ]
1135 cost = handle.split( ";" )[ 1 ]
1136 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001137 except AssertionError:
1138 main.log.exception( "" )
1139 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001140 except TypeError:
1141 main.log.exception( self.name + ": Object not as expected" )
1142 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001143 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001144 main.log.error( self.name + ": EOF exception found" )
1145 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001146 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001147 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001148 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001149 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001150
kelvin-onlabd3b64892015-01-20 13:26:24 -08001151 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001152 """
Jon Hallffb386d2014-11-21 13:43:38 -08001153 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001154 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001155 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001156 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001157 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001158 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001159 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001160 cmdStr += " -j"
1161 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001162 if handle:
1163 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001164 # TODO: Maybe make this less hardcoded
1165 # ConsistentMap Exceptions
1166 assert "org.onosproject.store.service" not in handle
1167 # Node not leader
1168 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001169 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001170 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001171 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001172 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001173 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001174 except TypeError:
1175 main.log.exception( self.name + ": Object not as expected" )
1176 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001177 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001178 main.log.error( self.name + ": EOF exception found" )
1179 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001180 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001181 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001182 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001183 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001184
kelvin-onlabd3b64892015-01-20 13:26:24 -08001185 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001186 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001187 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001188
Jon Hallefbd9792015-03-05 16:11:36 -08001189 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001190 partial mac address
1191
Jon Hall42db6dc2014-10-24 19:03:48 -04001192 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001193 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001194 try:
kelvin8ec71442015-01-15 16:57:00 -08001195 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001196 return None
1197 else:
1198 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001199 rawHosts = self.hosts()
1200 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001201 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001202 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001203 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001204 if not host:
1205 pass
1206 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001207 return host
1208 return None
Jon Hallc6793552016-01-19 14:18:37 -08001209 except ( TypeError, ValueError ):
1210 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001211 return None
Jon Hall42db6dc2014-10-24 19:03:48 -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()
Jon Hall42db6dc2014-10-24 19:03:48 -04001219
kelvin-onlabd3b64892015-01-20 13:26:24 -08001220 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001221 """
1222 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001223 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001224
andrewonlab3f0a4af2014-10-17 12:25:14 -04001225 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001226 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001227 IMPORTANT:
1228 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001229 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001230 Furthermore, it assumes that value of VLAN is '-1'
1231 Description:
kelvin8ec71442015-01-15 16:57:00 -08001232 Converts mininet hosts ( h1, h2, h3... ) into
1233 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1234 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001235 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001236 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001237
kelvin-onlabd3b64892015-01-20 13:26:24 -08001238 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001239 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001240 hostHex = hex( int( host ) ).zfill( 12 )
1241 hostHex = str( hostHex ).replace( 'x', '0' )
1242 i = iter( str( hostHex ) )
1243 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1244 hostHex = hostHex + "/-1"
1245 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001246
kelvin-onlabd3b64892015-01-20 13:26:24 -08001247 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001248
Jon Halld4d4b372015-01-28 16:02:41 -08001249 except TypeError:
1250 main.log.exception( self.name + ": Object not as expected" )
1251 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001252 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001253 main.log.error( self.name + ": EOF exception found" )
1254 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001255 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001256 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001257 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001258 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001259
You Wangbc898b82018-05-03 16:22:34 -07001260 def verifyHostLocation( self, hostIp, location ):
1261 """
1262 Description:
1263 Verify the host given is discovered in all locations expected
1264 Required:
1265 hostIp: IP address of the host
1266 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1267 Could be a string or list
1268 Returns:
1269 main.TRUE if host is discovered on all locations provided
1270 main.FALSE otherwise
1271 """
1272 import json
1273 locations = [ location ] if isinstance( location, str ) else location
1274 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1275 try:
1276 hosts = self.hosts()
1277 hosts = json.loads( hosts )
1278 targetHost = None
1279 for host in hosts:
1280 if hostIp in host[ "ipAddresses" ]:
1281 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001282 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001283 result = main.TRUE
1284 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1285 for loc in locations:
1286 discovered = False
1287 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001288 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1289 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001290 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001291 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001292 break
1293 if discovered:
1294 locationsDiscovered.remove( locDiscovered )
1295 else:
1296 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1297 result = main.FALSE
1298 if locationsDiscovered:
1299 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1300 result = main.FALSE
1301 return result
1302 except KeyError:
1303 main.log.exception( self.name + ": host data not as expected: " + hosts )
1304 return None
1305 except pexpect.EOF:
1306 main.log.error( self.name + ": EOF exception found" )
1307 main.log.error( self.name + ": " + self.handle.before )
1308 main.cleanAndExit()
1309 except Exception:
1310 main.log.exception( self.name + ": Uncaught exception" )
1311 return None
1312
You Wang53dba1e2018-02-02 17:45:44 -08001313 def verifyHostIp( self, hostList=[], prefix="" ):
1314 """
1315 Description:
1316 Verify that all hosts have IP address assigned to them
1317 Optional:
1318 hostList: If specified, verifications only happen to the hosts
1319 in hostList
1320 prefix: at least one of the ip address assigned to the host
1321 needs to have the specified prefix
1322 Returns:
1323 main.TRUE if all hosts have specific IP address assigned;
1324 main.FALSE otherwise
1325 """
1326 import json
1327 try:
1328 hosts = self.hosts()
1329 hosts = json.loads( hosts )
1330 if not hostList:
1331 hostList = [ host[ "id" ] for host in hosts ]
1332 for host in hosts:
1333 hostId = host[ "id" ]
1334 if hostId not in hostList:
1335 continue
1336 ipList = host[ "ipAddresses" ]
1337 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1338 if not ipList:
1339 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1340 else:
1341 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1342 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1343 else:
1344 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1345 hostList.remove( hostId )
1346 if hostList:
1347 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1348 return main.FALSE
1349 else:
1350 return main.TRUE
1351 except KeyError:
1352 main.log.exception( self.name + ": host data not as expected: " + hosts )
1353 return None
1354 except pexpect.EOF:
1355 main.log.error( self.name + ": EOF exception found" )
1356 main.log.error( self.name + ": " + self.handle.before )
1357 main.cleanAndExit()
1358 except Exception:
1359 main.log.exception( self.name + ": Uncaught exception" )
1360 return None
1361
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001362 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001363 """
andrewonlabe6745342014-10-17 14:29:13 -04001364 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001365 * hostIdOne: ONOS host id for host1
1366 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001367 Optional:
1368 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001369 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001370 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001371 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001372 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001373 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001374 Returns:
1375 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001376 """
andrewonlabe6745342014-10-17 14:29:13 -04001377 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001378 cmdStr = "add-host-intent "
1379 if vlanId:
1380 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001381 if setVlan:
1382 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001383 if encap:
1384 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001385 if bandwidth:
1386 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001387 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001388 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001389 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001390 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001391 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001392 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001393 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001394 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001395 else:
1396 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001397 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001398 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001399 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001400 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001401 else:
1402 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001403 main.log.debug( "Response from ONOS was: " +
1404 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001405 return None
Jon Hallc6793552016-01-19 14:18:37 -08001406 except AssertionError:
1407 main.log.exception( "" )
1408 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001409 except TypeError:
1410 main.log.exception( self.name + ": Object not as expected" )
1411 return None
andrewonlabe6745342014-10-17 14:29:13 -04001412 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001413 main.log.error( self.name + ": EOF exception found" )
1414 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001415 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001416 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001417 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001418 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001419
kelvin-onlabd3b64892015-01-20 13:26:24 -08001420 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001421 """
andrewonlab7b31d232014-10-24 13:31:47 -04001422 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001423 * ingressDevice: device id of ingress device
1424 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001425 Optional:
1426 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001427 Description:
1428 Adds an optical intent by specifying an ingress and egress device
1429 Returns:
1430 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001431 """
andrewonlab7b31d232014-10-24 13:31:47 -04001432 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001433 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1434 " " + str( egressDevice )
1435 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001436 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001437 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001438 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001439 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001440 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001441 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001442 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001443 main.log.info( "Optical intent installed between " +
1444 str( ingressDevice ) + " and " +
1445 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001446 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001447 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001448 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001449 else:
1450 main.log.error( "Error, intent ID not found" )
1451 return None
Jon Hallc6793552016-01-19 14:18:37 -08001452 except AssertionError:
1453 main.log.exception( "" )
1454 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001455 except TypeError:
1456 main.log.exception( self.name + ": Object not as expected" )
1457 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001458 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001459 main.log.error( self.name + ": EOF exception found" )
1460 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001461 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001462 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001463 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001464 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001465
kelvin-onlabd3b64892015-01-20 13:26:24 -08001466 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001467 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001468 ingressDevice,
1469 egressDevice,
1470 portIngress="",
1471 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001472 ethType="",
1473 ethSrc="",
1474 ethDst="",
1475 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001476 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001477 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001478 ipProto="",
1479 ipSrc="",
1480 ipDst="",
1481 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001482 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001483 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001484 setVlan="",
1485 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001486 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001487 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001488 * ingressDevice: device id of ingress device
1489 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001490 Optional:
1491 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001492 * ethSrc: specify ethSrc ( i.e. src mac addr )
1493 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001494 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001495 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001496 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001497 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001498 * ipSrc: specify ip source address
1499 * ipDst: specify ip destination address
1500 * tcpSrc: specify tcp source port
1501 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001502 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001503 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001504 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001505 Description:
kelvin8ec71442015-01-15 16:57:00 -08001506 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001507 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001508 Returns:
1509 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001510
Jon Halle3f39ff2015-01-13 11:50:53 -08001511 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001512 options developers provide for point-to-point
1513 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001514 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001515 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001516 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001517
Jeremy Songsterff553672016-05-12 17:06:23 -07001518 if ethType:
1519 cmd += " --ethType " + str( ethType )
1520 if ethSrc:
1521 cmd += " --ethSrc " + str( ethSrc )
1522 if ethDst:
1523 cmd += " --ethDst " + str( ethDst )
1524 if bandwidth:
1525 cmd += " --bandwidth " + str( bandwidth )
1526 if lambdaAlloc:
1527 cmd += " --lambda "
1528 if ipProto:
1529 cmd += " --ipProto " + str( ipProto )
1530 if ipSrc:
1531 cmd += " --ipSrc " + str( ipSrc )
1532 if ipDst:
1533 cmd += " --ipDst " + str( ipDst )
1534 if tcpSrc:
1535 cmd += " --tcpSrc " + str( tcpSrc )
1536 if tcpDst:
1537 cmd += " --tcpDst " + str( tcpDst )
1538 if vlanId:
1539 cmd += " -v " + str( vlanId )
1540 if setVlan:
1541 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001542 if encap:
1543 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001544 if protected:
1545 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001546
kelvin8ec71442015-01-15 16:57:00 -08001547 # Check whether the user appended the port
1548 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001549 if "/" in ingressDevice:
1550 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001551 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001552 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001553 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001554 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001555 # Would it make sense to throw an exception and exit
1556 # the test?
1557 return None
andrewonlab36af3822014-11-18 17:48:18 -05001558
kelvin8ec71442015-01-15 16:57:00 -08001559 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001560 str( ingressDevice ) + "/" +\
1561 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001562
kelvin-onlabd3b64892015-01-20 13:26:24 -08001563 if "/" in egressDevice:
1564 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001565 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001566 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001567 main.log.error( "You must specify the egress port" )
1568 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001569
kelvin8ec71442015-01-15 16:57:00 -08001570 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001571 str( egressDevice ) + "/" +\
1572 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001573
kelvin-onlab898a6c62015-01-16 14:13:53 -08001574 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001575 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001576 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001577 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001578 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001579 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001580 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001581 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001582 # TODO: print out all the options in this message?
1583 main.log.info( "Point-to-point intent installed between " +
1584 str( ingressDevice ) + " and " +
1585 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001586 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001587 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001588 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001589 else:
1590 main.log.error( "Error, intent ID not found" )
1591 return None
Jon Hallc6793552016-01-19 14:18:37 -08001592 except AssertionError:
1593 main.log.exception( "" )
1594 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001595 except TypeError:
1596 main.log.exception( self.name + ": Object not as expected" )
1597 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001598 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001599 main.log.error( self.name + ": EOF exception found" )
1600 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001601 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001602 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001603 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001604 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001605
kelvin-onlabd3b64892015-01-20 13:26:24 -08001606 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001607 self,
shahshreyac2f97072015-03-19 17:04:29 -07001608 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001609 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001610 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001611 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001612 ethType="",
1613 ethSrc="",
1614 ethDst="",
1615 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001616 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001617 ipProto="",
1618 ipSrc="",
1619 ipDst="",
1620 tcpSrc="",
1621 tcpDst="",
1622 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001623 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001624 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001625 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001626 partial=False,
1627 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001628 """
shahshreyad0c80432014-12-04 16:56:05 -08001629 Note:
shahshreya70622b12015-03-19 17:19:00 -07001630 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001631 is same. That is, all ingress devices include port numbers
1632 with a "/" or all ingress devices could specify device
1633 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001634 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001635 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001636 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001637 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001638 Optional:
1639 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001640 * ethSrc: specify ethSrc ( i.e. src mac addr )
1641 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001642 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001643 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001644 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001645 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001646 * ipSrc: specify ip source address
1647 * ipDst: specify ip destination address
1648 * tcpSrc: specify tcp source port
1649 * tcpDst: specify tcp destination port
1650 * setEthSrc: action to Rewrite Source MAC Address
1651 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001652 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001653 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001654 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001655 Description:
kelvin8ec71442015-01-15 16:57:00 -08001656 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001657 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001658 Returns:
1659 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001660
Jon Halle3f39ff2015-01-13 11:50:53 -08001661 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001662 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001663 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001664 """
shahshreyad0c80432014-12-04 16:56:05 -08001665 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001666 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001667
Jeremy Songsterff553672016-05-12 17:06:23 -07001668 if ethType:
1669 cmd += " --ethType " + str( ethType )
1670 if ethSrc:
1671 cmd += " --ethSrc " + str( ethSrc )
1672 if ethDst:
1673 cmd += " --ethDst " + str( ethDst )
1674 if bandwidth:
1675 cmd += " --bandwidth " + str( bandwidth )
1676 if lambdaAlloc:
1677 cmd += " --lambda "
1678 if ipProto:
1679 cmd += " --ipProto " + str( ipProto )
1680 if ipSrc:
1681 cmd += " --ipSrc " + str( ipSrc )
1682 if ipDst:
1683 cmd += " --ipDst " + str( ipDst )
1684 if tcpSrc:
1685 cmd += " --tcpSrc " + str( tcpSrc )
1686 if tcpDst:
1687 cmd += " --tcpDst " + str( tcpDst )
1688 if setEthSrc:
1689 cmd += " --setEthSrc " + str( setEthSrc )
1690 if setEthDst:
1691 cmd += " --setEthDst " + str( setEthDst )
1692 if vlanId:
1693 cmd += " -v " + str( vlanId )
1694 if setVlan:
1695 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001696 if partial:
1697 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001698 if encap:
1699 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001700
kelvin8ec71442015-01-15 16:57:00 -08001701 # Check whether the user appended the port
1702 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001703
1704 if portIngressList is None:
1705 for ingressDevice in ingressDeviceList:
1706 if "/" in ingressDevice:
1707 cmd += " " + str( ingressDevice )
1708 else:
1709 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001710 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001711 # TODO: perhaps more meaningful return
1712 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001713 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001714 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001715 for ingressDevice, portIngress in zip( ingressDeviceList,
1716 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001717 cmd += " " + \
1718 str( ingressDevice ) + "/" +\
1719 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001720 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001721 main.log.error( "Device list and port list does not " +
1722 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001723 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001724 if "/" in egressDevice:
1725 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001726 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001727 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001728 main.log.error( "You must specify " +
1729 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001730 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001731
kelvin8ec71442015-01-15 16:57:00 -08001732 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001733 str( egressDevice ) + "/" +\
1734 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001735 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001736 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001737 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001738 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001739 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001740 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001741 "intent" )
1742 return None
shahshreyad0c80432014-12-04 16:56:05 -08001743 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001744 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001745 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001746 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001747 else:
1748 main.log.error( "Error, intent ID not found" )
1749 return None
Jon Hallc6793552016-01-19 14:18:37 -08001750 except AssertionError:
1751 main.log.exception( "" )
1752 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001753 except TypeError:
1754 main.log.exception( self.name + ": Object not as expected" )
1755 return None
1756 except pexpect.EOF:
1757 main.log.error( self.name + ": EOF exception found" )
1758 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001759 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001760 except Exception:
1761 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001762 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001763
1764 def addSinglepointToMultipointIntent(
1765 self,
1766 ingressDevice,
1767 egressDeviceList,
1768 portIngress="",
1769 portEgressList=None,
1770 ethType="",
1771 ethSrc="",
1772 ethDst="",
1773 bandwidth="",
1774 lambdaAlloc=False,
1775 ipProto="",
1776 ipSrc="",
1777 ipDst="",
1778 tcpSrc="",
1779 tcpDst="",
1780 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001781 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001782 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001783 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001784 partial=False,
1785 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001786 """
1787 Note:
1788 This function assumes the format of all egress devices
1789 is same. That is, all egress devices include port numbers
1790 with a "/" or all egress devices could specify device
1791 ids and port numbers seperately.
1792 Required:
1793 * EgressDeviceList: List of device ids of egress device
1794 ( Atleast 2 eress devices required in the list )
1795 * ingressDevice: device id of ingress device
1796 Optional:
1797 * ethType: specify ethType
1798 * ethSrc: specify ethSrc ( i.e. src mac addr )
1799 * ethDst: specify ethDst ( i.e. dst mac addr )
1800 * bandwidth: specify bandwidth capacity of link
1801 * lambdaAlloc: if True, intent will allocate lambda
1802 for the specified intent
1803 * ipProto: specify ip protocol
1804 * ipSrc: specify ip source address
1805 * ipDst: specify ip destination address
1806 * tcpSrc: specify tcp source port
1807 * tcpDst: specify tcp destination port
1808 * setEthSrc: action to Rewrite Source MAC Address
1809 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001810 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001811 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001812 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001813 Description:
1814 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1815 specifying device id's and optional fields
1816 Returns:
1817 A string of the intent id or None on error
1818
1819 NOTE: This function may change depending on the
1820 options developers provide for singlepoint-to-multipoint
1821 intent via cli
1822 """
1823 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001824 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001825
Jeremy Songsterff553672016-05-12 17:06:23 -07001826 if ethType:
1827 cmd += " --ethType " + str( ethType )
1828 if ethSrc:
1829 cmd += " --ethSrc " + str( ethSrc )
1830 if ethDst:
1831 cmd += " --ethDst " + str( ethDst )
1832 if bandwidth:
1833 cmd += " --bandwidth " + str( bandwidth )
1834 if lambdaAlloc:
1835 cmd += " --lambda "
1836 if ipProto:
1837 cmd += " --ipProto " + str( ipProto )
1838 if ipSrc:
1839 cmd += " --ipSrc " + str( ipSrc )
1840 if ipDst:
1841 cmd += " --ipDst " + str( ipDst )
1842 if tcpSrc:
1843 cmd += " --tcpSrc " + str( tcpSrc )
1844 if tcpDst:
1845 cmd += " --tcpDst " + str( tcpDst )
1846 if setEthSrc:
1847 cmd += " --setEthSrc " + str( setEthSrc )
1848 if setEthDst:
1849 cmd += " --setEthDst " + str( setEthDst )
1850 if vlanId:
1851 cmd += " -v " + str( vlanId )
1852 if setVlan:
1853 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001854 if partial:
1855 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001856 if encap:
1857 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001858
1859 # Check whether the user appended the port
1860 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001861
kelvin-onlabb9408212015-04-01 13:34:04 -07001862 if "/" in ingressDevice:
1863 cmd += " " + str( ingressDevice )
1864 else:
1865 if not portIngress:
1866 main.log.error( "You must specify " +
1867 "the Ingress port" )
1868 return main.FALSE
1869
1870 cmd += " " +\
1871 str( ingressDevice ) + "/" +\
1872 str( portIngress )
1873
1874 if portEgressList is None:
1875 for egressDevice in egressDeviceList:
1876 if "/" in egressDevice:
1877 cmd += " " + str( egressDevice )
1878 else:
1879 main.log.error( "You must specify " +
1880 "the egress port" )
1881 # TODO: perhaps more meaningful return
1882 return main.FALSE
1883 else:
1884 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001885 for egressDevice, portEgress in zip( egressDeviceList,
1886 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001887 cmd += " " + \
1888 str( egressDevice ) + "/" +\
1889 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001890 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001891 main.log.error( "Device list and port list does not " +
1892 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001893 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001894 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001895 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001896 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001897 # If error, return error message
1898 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001899 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001900 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001901 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001902 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001903 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001904 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001905 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001906 else:
1907 main.log.error( "Error, intent ID not found" )
1908 return None
Jon Hallc6793552016-01-19 14:18:37 -08001909 except AssertionError:
1910 main.log.exception( "" )
1911 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001912 except TypeError:
1913 main.log.exception( self.name + ": Object not as expected" )
1914 return None
shahshreyad0c80432014-12-04 16:56:05 -08001915 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001916 main.log.error( self.name + ": EOF exception found" )
1917 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001918 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001919 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001920 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001921 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001922
Hari Krishna9e232602015-04-13 17:29:08 -07001923 def addMplsIntent(
1924 self,
1925 ingressDevice,
1926 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001927 ingressPort="",
1928 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001929 ethType="",
1930 ethSrc="",
1931 ethDst="",
1932 bandwidth="",
1933 lambdaAlloc=False,
1934 ipProto="",
1935 ipSrc="",
1936 ipDst="",
1937 tcpSrc="",
1938 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001939 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001940 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001941 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001942 """
1943 Required:
1944 * ingressDevice: device id of ingress device
1945 * egressDevice: device id of egress device
1946 Optional:
1947 * ethType: specify ethType
1948 * ethSrc: specify ethSrc ( i.e. src mac addr )
1949 * ethDst: specify ethDst ( i.e. dst mac addr )
1950 * bandwidth: specify bandwidth capacity of link
1951 * lambdaAlloc: if True, intent will allocate lambda
1952 for the specified intent
1953 * ipProto: specify ip protocol
1954 * ipSrc: specify ip source address
1955 * ipDst: specify ip destination address
1956 * tcpSrc: specify tcp source port
1957 * tcpDst: specify tcp destination port
1958 * ingressLabel: Ingress MPLS label
1959 * egressLabel: Egress MPLS label
1960 Description:
1961 Adds MPLS intent by
1962 specifying device id's and optional fields
1963 Returns:
1964 A string of the intent id or None on error
1965
1966 NOTE: This function may change depending on the
1967 options developers provide for MPLS
1968 intent via cli
1969 """
1970 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001971 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001972
Jeremy Songsterff553672016-05-12 17:06:23 -07001973 if ethType:
1974 cmd += " --ethType " + str( ethType )
1975 if ethSrc:
1976 cmd += " --ethSrc " + str( ethSrc )
1977 if ethDst:
1978 cmd += " --ethDst " + str( ethDst )
1979 if bandwidth:
1980 cmd += " --bandwidth " + str( bandwidth )
1981 if lambdaAlloc:
1982 cmd += " --lambda "
1983 if ipProto:
1984 cmd += " --ipProto " + str( ipProto )
1985 if ipSrc:
1986 cmd += " --ipSrc " + str( ipSrc )
1987 if ipDst:
1988 cmd += " --ipDst " + str( ipDst )
1989 if tcpSrc:
1990 cmd += " --tcpSrc " + str( tcpSrc )
1991 if tcpDst:
1992 cmd += " --tcpDst " + str( tcpDst )
1993 if ingressLabel:
1994 cmd += " --ingressLabel " + str( ingressLabel )
1995 if egressLabel:
1996 cmd += " --egressLabel " + str( egressLabel )
1997 if priority:
1998 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001999
2000 # Check whether the user appended the port
2001 # or provided it as an input
2002 if "/" in ingressDevice:
2003 cmd += " " + str( ingressDevice )
2004 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002005 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002006 main.log.error( "You must specify the ingress port" )
2007 return None
2008
2009 cmd += " " + \
2010 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002011 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07002012
2013 if "/" in egressDevice:
2014 cmd += " " + str( egressDevice )
2015 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002016 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002017 main.log.error( "You must specify the egress port" )
2018 return None
2019
2020 cmd += " " +\
2021 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002022 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07002023
2024 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08002025 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002026 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07002027 # If error, return error message
2028 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002029 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07002030 return None
2031 else:
2032 # TODO: print out all the options in this message?
2033 main.log.info( "MPLS intent installed between " +
2034 str( ingressDevice ) + " and " +
2035 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002036 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07002037 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002038 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07002039 else:
2040 main.log.error( "Error, intent ID not found" )
2041 return None
Jon Hallc6793552016-01-19 14:18:37 -08002042 except AssertionError:
2043 main.log.exception( "" )
2044 return None
Hari Krishna9e232602015-04-13 17:29:08 -07002045 except TypeError:
2046 main.log.exception( self.name + ": Object not as expected" )
2047 return None
2048 except pexpect.EOF:
2049 main.log.error( self.name + ": EOF exception found" )
2050 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002051 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002052 except Exception:
2053 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002054 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002055
Jon Hallefbd9792015-03-05 16:11:36 -08002056 def removeIntent( self, intentId, app='org.onosproject.cli',
2057 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002058 """
shahshreya1c818fc2015-02-26 13:44:08 -08002059 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07002060 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08002061 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07002062 -p or --purge: Purge the intent from the store after removal
2063
Jon Halle3f39ff2015-01-13 11:50:53 -08002064 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002065 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002066 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002067 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002068 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002069 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002070 if purge:
2071 cmdStr += " -p"
2072 if sync:
2073 cmdStr += " -s"
2074
2075 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002076 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002077 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002078 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002079 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002080 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002081 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002082 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002083 # TODO: Should this be main.TRUE
2084 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002085 except AssertionError:
2086 main.log.exception( "" )
2087 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002088 except TypeError:
2089 main.log.exception( self.name + ": Object not as expected" )
2090 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002091 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002092 main.log.error( self.name + ": EOF exception found" )
2093 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002094 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002095 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002096 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002097 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002098
YPZhangfebf7302016-05-24 16:45:56 -07002099 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002100 """
2101 Description:
2102 Remove all the intents
2103 Optional args:-
2104 -s or --sync: Waits for the removal before returning
2105 -p or --purge: Purge the intent from the store after removal
2106 Returns:
2107 Returns main.TRUE if all intents are removed, otherwise returns
2108 main.FALSE; Returns None for exception
2109 """
2110 try:
2111 cmdStr = "remove-intent"
2112 if purge:
2113 cmdStr += " -p"
2114 if sync:
2115 cmdStr += " -s"
2116
2117 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002118 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002119 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002120 assert "Command not found:" not in handle, handle
2121 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002122 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002123 return main.FALSE
2124 else:
2125 return main.TRUE
2126 except AssertionError:
2127 main.log.exception( "" )
2128 return None
2129 except TypeError:
2130 main.log.exception( self.name + ": Object not as expected" )
2131 return None
2132 except pexpect.EOF:
2133 main.log.error( self.name + ": EOF exception found" )
2134 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002135 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002136 except Exception:
2137 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002138 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002139
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002140 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002141 """
2142 Purges all WITHDRAWN Intents
2143 """
2144 try:
2145 cmdStr = "purge-intents"
2146 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002147 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002148 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002149 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002150 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002151 return main.FALSE
2152 else:
2153 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002154 except AssertionError:
2155 main.log.exception( "" )
2156 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002157 except TypeError:
2158 main.log.exception( self.name + ": Object not as expected" )
2159 return None
2160 except pexpect.EOF:
2161 main.log.error( self.name + ": EOF exception found" )
2162 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002163 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002164 except Exception:
2165 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002166 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002167
Devin Lime6fe3c42017-10-18 16:28:40 -07002168 def wipeout( self ):
2169 """
2170 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2171 """
2172 try:
2173 cmdStr = "wipe-out please"
2174 handle = self.sendline( cmdStr, timeout=60 )
2175 assert handle is not None, "Error in sendline"
2176 assert "Command not found:" not in handle, handle
2177 return main.TRUE
2178 except AssertionError:
2179 main.log.exception( "" )
2180 return None
2181 except TypeError:
2182 main.log.exception( self.name + ": Object not as expected" )
2183 return None
2184 except pexpect.EOF:
2185 main.log.error( self.name + ": EOF exception found" )
2186 main.log.error( self.name + ": " + self.handle.before )
2187 main.cleanAndExit()
2188 except Exception:
2189 main.log.exception( self.name + ": Uncaught exception!" )
2190 main.cleanAndExit()
2191
kelvin-onlabd3b64892015-01-20 13:26:24 -08002192 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002193 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002194 NOTE: This method should be used after installing application:
2195 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002196 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002197 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002198 Description:
2199 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002200 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002201 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002202 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002203 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002204 cmdStr += " -j"
2205 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002206 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002207 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002208 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002209 except AssertionError:
2210 main.log.exception( "" )
2211 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002212 except TypeError:
2213 main.log.exception( self.name + ": Object not as expected" )
2214 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002215 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002216 main.log.error( self.name + ": EOF exception found" )
2217 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002218 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002219 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002220 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002221 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002222
pingping-lin54b03372015-08-13 14:43:10 -07002223 def ipv4RouteNumber( self ):
2224 """
2225 NOTE: This method should be used after installing application:
2226 onos-app-sdnip
2227 Description:
2228 Obtain the total IPv4 routes number in the system
2229 """
2230 try:
Pratik Parab57963572017-05-09 11:37:54 -07002231 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002232 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002233 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002234 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002235 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002236 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002237 except AssertionError:
2238 main.log.exception( "" )
2239 return None
2240 except ( TypeError, ValueError ):
2241 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002242 return None
2243 except pexpect.EOF:
2244 main.log.error( self.name + ": EOF exception found" )
2245 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002246 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002247 except Exception:
2248 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002249 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002250
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002251 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002252 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002253 """
2254 Description:
2255 Obtain Bandwidth Allocation Information from ONOS cli.
2256 """
2257 try:
2258 cmdStr = "allocations"
2259 if jsonFormat:
2260 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002261 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002262 assert handle is not None, "Error in sendline"
2263 assert "Command not found:" not in handle, handle
2264 return handle
2265 except AssertionError:
2266 main.log.exception( "" )
2267 return None
2268 except ( TypeError, ValueError ):
2269 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2270 return None
2271 except pexpect.EOF:
2272 main.log.error( self.name + ": EOF exception found" )
2273 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002274 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002275 except Exception:
2276 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002277 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002278
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002279 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002280 """
andrewonlabe6745342014-10-17 14:29:13 -04002281 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002282 Obtain intents from the ONOS cli.
2283 Optional:
2284 * jsonFormat: Enable output formatting in json, default to True
2285 * summary: Whether only output the intent summary, defaults to False
2286 * type: Only output a certain type of intent. This options is valid
2287 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002288 """
andrewonlabe6745342014-10-17 14:29:13 -04002289 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002290 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002291 if summary:
2292 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002293 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002294 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002295 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002296 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002297 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002298 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002299 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002300 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002301 else:
Jon Hallff566d52016-01-15 14:45:36 -08002302 intentType = ""
2303 # IF we want the summary of a specific intent type
2304 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002305 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002306 if intentType in jsonResult.keys():
2307 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002308 else:
Jon Hallff566d52016-01-15 14:45:36 -08002309 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002310 return handle
2311 else:
2312 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002313 except AssertionError:
2314 main.log.exception( "" )
2315 return None
2316 except ( TypeError, ValueError ):
2317 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002318 return None
2319 except pexpect.EOF:
2320 main.log.error( self.name + ": EOF exception found" )
2321 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002322 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002323 except Exception:
2324 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002325 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002326
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002327 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002328 """
You Wangfdcbfc42016-05-16 12:16:53 -07002329 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002330 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002331 list of intent IDs.
2332 Parameters:
2333 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002334 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002335 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002336 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002337 accepted.
2338 Returns a list of dictionaries if a list of intent IDs is accepted,
2339 and each dictionary maps 'id' to the Intent ID and 'state' to
2340 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002341 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002342
kelvin-onlab54400a92015-02-26 18:05:51 -08002343 try:
2344 state = "State is Undefined"
2345 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002346 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002347 else:
Jon Hallc6793552016-01-19 14:18:37 -08002348 rawJson = intentsJson
2349 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002350 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002351 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002352 if intentsId == intent[ 'id' ]:
2353 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002354 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002355 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002356 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002357 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002358 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002359 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002360 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002361 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002362 for intent in parsedIntentsJson:
2363 if intentsId[ i ] == intent[ 'id' ]:
2364 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002365 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002366 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002367 break
Jon Hallefbd9792015-03-05 16:11:36 -08002368 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002369 main.log.warn( "Could not find all intents in ONOS output" )
2370 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002371 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002372 else:
Jon Hall53158082017-05-18 11:17:00 -07002373 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002374 return None
Jon Hallc6793552016-01-19 14:18:37 -08002375 except ( TypeError, ValueError ):
2376 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002377 return None
2378 except pexpect.EOF:
2379 main.log.error( self.name + ": EOF exception found" )
2380 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002381 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002382 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002383 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002384 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002385
Jon Hallf539eb92017-05-22 17:18:42 -07002386 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002387 """
2388 Description:
2389 Check intents state
2390 Required:
2391 intentsId - List of intents ID to be checked
2392 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002393 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002394 state in the list.
2395 *NOTE: You can pass in a list of expected state,
2396 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002397 Return:
Jon Hall53158082017-05-18 11:17:00 -07002398 Returns main.TRUE only if all intent are the same as expected states,
2399 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002400 """
2401 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002402 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002403 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002404
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002405 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002406 intentsDict = []
2407 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002408 if isinstance( intentsId, types.StringType ) \
2409 and intent.get( 'id' ) == intentsId:
2410 intentsDict.append( intent )
2411 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002412 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002413 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002414
2415 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002416 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002417 "getting intents state" )
2418 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002419
2420 if isinstance( expectedState, types.StringType ):
2421 for intents in intentsDict:
2422 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002423 main.log.debug( self.name + " : Intent ID - " +
2424 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002425 " actual state = " +
2426 intents.get( 'state' )
2427 + " does not equal expected state = "
2428 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002429 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002430 elif isinstance( expectedState, types.ListType ):
2431 for intents in intentsDict:
2432 if not any( state == intents.get( 'state' ) for state in
2433 expectedState ):
2434 main.log.debug( self.name + " : Intent ID - " +
2435 intents.get( 'id' ) +
2436 " actual state = " +
2437 intents.get( 'state' ) +
2438 " does not equal expected states = "
2439 + str( expectedState ) )
2440 returnValue = main.FALSE
2441
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002442 if returnValue == main.TRUE:
2443 main.log.info( self.name + ": All " +
2444 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002445 " intents are in " + str( expectedState ) +
2446 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002447 return returnValue
2448 except TypeError:
2449 main.log.exception( self.name + ": Object not as expected" )
2450 return None
2451 except pexpect.EOF:
2452 main.log.error( self.name + ": EOF exception found" )
2453 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002454 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002455 except Exception:
2456 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002457 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002458
Jon Hallf539eb92017-05-22 17:18:42 -07002459 def compareBandwidthAllocations( self, expectedAllocations ):
2460 """
2461 Description:
2462 Compare the allocated bandwidth with the given allocations
2463 Required:
2464 expectedAllocations - The expected ONOS output of the allocations command
2465 Return:
2466 Returns main.TRUE only if all intent are the same as expected states,
2467 otherwise returns main.FALSE.
2468 """
2469 # FIXME: Convert these string comparisons to object comparisons
2470 try:
2471 returnValue = main.TRUE
2472 bandwidthFailed = False
2473 rawAlloc = self.allocations()
2474 expectedFormat = StringIO( expectedAllocations )
2475 ONOSOutput = StringIO( rawAlloc )
2476 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2477 str( expectedFormat ) ) )
2478
2479 for actual, expected in izip( ONOSOutput, expectedFormat ):
2480 actual = actual.rstrip()
2481 expected = expected.rstrip()
2482 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2483 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002484 marker1 = actual.find( 'allocated' )
2485 m1 = actual[ :marker1 ]
2486 marker2 = expected.find( 'allocated' )
2487 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002488 if m1 != m2:
2489 bandwidthFailed = True
2490 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2491 bandwidthFailed = True
2492 expectedFormat.close()
2493 ONOSOutput.close()
2494
2495 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002496 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002497 returnValue = main.FALSE
2498 return returnValue
2499 except TypeError:
2500 main.log.exception( self.name + ": Object not as expected" )
2501 return None
2502 except pexpect.EOF:
2503 main.log.error( self.name + ": EOF exception found" )
2504 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002505 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002506 except Exception:
2507 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002508 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002509
You Wang66518af2016-05-16 15:32:59 -07002510 def compareIntent( self, intentDict ):
2511 """
2512 Description:
2513 Compare the intent ids and states provided in the argument with all intents in ONOS
2514 Return:
2515 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2516 Arguments:
2517 intentDict: a dictionary which maps intent ids to intent states
2518 """
2519 try:
2520 intentsRaw = self.intents()
2521 intentsJson = json.loads( intentsRaw )
2522 intentDictONOS = {}
2523 for intent in intentsJson:
2524 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002525 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002526 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002527 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002528 str( len( intentDict ) ) + " expected and " +
2529 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002530 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002531 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002532 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002533 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2534 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002535 else:
2536 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2537 main.log.debug( self.name + ": intent ID - " + intentID +
2538 " expected state is " + intentDict[ intentID ] +
2539 " but actual state is " + intentDictONOS[ intentID ] )
2540 returnValue = main.FALSE
2541 intentDictONOS.pop( intentID )
2542 if len( intentDictONOS ) > 0:
2543 returnValue = main.FALSE
2544 for intentID in intentDictONOS.keys():
2545 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002546 if returnValue == main.TRUE:
2547 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2548 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002549 except KeyError:
2550 main.log.exception( self.name + ": KeyError exception found" )
2551 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002552 except ( TypeError, ValueError ):
2553 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002554 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002555 except pexpect.EOF:
2556 main.log.error( self.name + ": EOF exception found" )
2557 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002558 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002559 except Exception:
2560 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002561 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002562
YPZhang14a4aa92016-07-15 13:37:15 -07002563 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002564 """
2565 Description:
2566 Check the number of installed intents.
2567 Optional:
2568 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002569 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002570 Return:
2571 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2572 , otherwise, returns main.FALSE.
2573 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002574
GlennRCed771242016-01-13 17:02:47 -08002575 try:
2576 cmd = "intents -s -j"
2577
2578 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002579 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002580 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002581 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002582 response = json.loads( response )
2583
2584 # get total and installed number, see if they are match
2585 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002586 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002587 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2588 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002589 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002590 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2591 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002592 return main.FALSE
2593
Jon Hallc6793552016-01-19 14:18:37 -08002594 except ( TypeError, ValueError ):
2595 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002596 return None
2597 except pexpect.EOF:
2598 main.log.error( self.name + ": EOF exception found" )
2599 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002600 if noExit:
2601 return main.FALSE
2602 else:
Devin Lim44075962017-08-11 10:56:37 -07002603 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002604 except pexpect.TIMEOUT:
2605 main.log.error( self.name + ": ONOS timeout" )
2606 return None
GlennRCed771242016-01-13 17:02:47 -08002607 except Exception:
2608 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002609 if noExit:
2610 return main.FALSE
2611 else:
Devin Lim44075962017-08-11 10:56:37 -07002612 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002613
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002614 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002615 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002616 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002617 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002618 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002619 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002620 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002621 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002622 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002623 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002624 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002625 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002626 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002627 cmdStr += " -n"
2628 cmdStr += " " + state
2629 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002630 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002631 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002632 assert "Command not found:" not in handle, handle
2633 if re.search( "Error:", handle ):
2634 main.log.error( self.name + ": flows() response: " +
2635 str( handle ) )
2636 return handle
2637 except AssertionError:
2638 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002639 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002640 except TypeError:
2641 main.log.exception( self.name + ": Object not as expected" )
2642 return None
Jon Hallc6793552016-01-19 14:18:37 -08002643 except pexpect.TIMEOUT:
2644 main.log.error( self.name + ": ONOS timeout" )
2645 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002646 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002647 main.log.error( self.name + ": EOF exception found" )
2648 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002649 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002650 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002651 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002652 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002653
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002654 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002655 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002656 count = int( count ) if count else 0
2657 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002658
Jon Halle0f0b342017-04-18 11:43:47 -07002659 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002660 """
2661 Description:
GlennRCed771242016-01-13 17:02:47 -08002662 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002663 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2664 if the count of those states is 0, which means all current flows
2665 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002666 Optional:
GlennRCed771242016-01-13 17:02:47 -08002667 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002668 Return:
2669 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002670 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002671 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002672 """
2673 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002674 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002675 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002676 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002677 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002678 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002679 if rawFlows:
2680 # if we didn't get flows or flows function return None, we should return
2681 # main.Flase
2682 checkedStates.append( json.loads( rawFlows ) )
2683 else:
2684 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002685 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002686 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002687 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002688 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002689 except TypeError:
2690 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002691 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002692
GlennRCed771242016-01-13 17:02:47 -08002693 # We want to count PENDING_ADD if isPENDING is true
2694 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002695 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002696 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002697 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002698 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002699 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002700 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002701 except ( TypeError, ValueError ):
2702 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002703 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002704
YPZhang240842b2016-05-17 12:00:50 -07002705 except AssertionError:
2706 main.log.exception( "" )
2707 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002708 except pexpect.TIMEOUT:
2709 main.log.error( self.name + ": ONOS timeout" )
2710 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002711 except pexpect.EOF:
2712 main.log.error( self.name + ": EOF exception found" )
2713 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002714 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002715 except Exception:
2716 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002717 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002718
GlennRCed771242016-01-13 17:02:47 -08002719 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002720 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002721 """
andrewonlab87852b02014-11-19 18:44:19 -05002722 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002723 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002724 a specific point-to-point intent definition
2725 Required:
GlennRCed771242016-01-13 17:02:47 -08002726 * ingress: specify source dpid
2727 * egress: specify destination dpid
2728 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002729 Optional:
GlennRCed771242016-01-13 17:02:47 -08002730 * offset: the keyOffset is where the next batch of intents
2731 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002732 * noExit: If set to True, TestON will not exit if any error when issus command
2733 * getResponse: If set to True, function will return ONOS response.
2734
GlennRCed771242016-01-13 17:02:47 -08002735 Returns: If failed to push test intents, it will returen None,
2736 if successful, return true.
2737 Timeout expection will return None,
2738 TypeError will return false
2739 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002740 """
andrewonlab87852b02014-11-19 18:44:19 -05002741 try:
GlennRCed771242016-01-13 17:02:47 -08002742 if background:
2743 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002744 else:
GlennRCed771242016-01-13 17:02:47 -08002745 back = ""
2746 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002747 ingress,
2748 egress,
2749 batchSize,
2750 offset,
2751 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002752 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002753 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002754 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002755 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002756 if getResponse:
2757 return response
2758
GlennRCed771242016-01-13 17:02:47 -08002759 # TODO: We should handle if there is failure in installation
2760 return main.TRUE
2761
Jon Hallc6793552016-01-19 14:18:37 -08002762 except AssertionError:
2763 main.log.exception( "" )
2764 return None
GlennRCed771242016-01-13 17:02:47 -08002765 except pexpect.TIMEOUT:
2766 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002767 return None
andrewonlab87852b02014-11-19 18:44:19 -05002768 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002769 main.log.error( self.name + ": EOF exception found" )
2770 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002771 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002772 except TypeError:
2773 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002774 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002775 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002776 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002777 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002778
YPZhangebf9eb52016-05-12 15:20:24 -07002779 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002780 """
2781 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002782 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002783 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002784 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002785 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002786 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002787
YPZhangb5d3f832016-01-23 22:54:26 -08002788 try:
YPZhange3109a72016-02-02 11:25:37 -08002789 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002790 cmd = "flows -c added"
2791 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2792 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002793 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002794 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002795 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002796 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002797 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002798 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002799 return None
2800 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002801
You Wangd3cb2ce2016-05-16 14:01:24 -07002802 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002803 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002804 return None
2805 except pexpect.EOF:
2806 main.log.error( self.name + ": EOF exception found" )
2807 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002808 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002809 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002810 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002811 except pexpect.TIMEOUT:
2812 main.log.error( self.name + ": ONOS timeout" )
2813 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002814 except Exception:
2815 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002816 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002817 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002818 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002819
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002820 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002821 """
2822 Description:
2823 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002824 Optional:
2825 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002826 Return:
2827 The number of intents
2828 """
2829 try:
2830 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002831 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002832 if response is None:
2833 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002834 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002835 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002836 except ( TypeError, ValueError ):
2837 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002838 return None
2839 except pexpect.EOF:
2840 main.log.error( self.name + ": EOF exception found" )
2841 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002842 if noExit:
2843 return -1
2844 else:
Devin Lim44075962017-08-11 10:56:37 -07002845 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002846 except Exception:
2847 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002848 if noExit:
2849 return -1
2850 else:
Devin Lim44075962017-08-11 10:56:37 -07002851 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002852
kelvin-onlabd3b64892015-01-20 13:26:24 -08002853 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002854 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002855 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002856 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002857 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002858 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002859 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002860 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002861 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002862 cmdStr += " -j"
2863 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002864 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002865 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002866 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002867 except AssertionError:
2868 main.log.exception( "" )
2869 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002870 except TypeError:
2871 main.log.exception( self.name + ": Object not as expected" )
2872 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002873 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002874 main.log.error( self.name + ": EOF exception found" )
2875 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002876 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002877 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002878 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002879 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002880
kelvin-onlabd3b64892015-01-20 13:26:24 -08002881 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002882 """
2883 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002884 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002885 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002886 """
andrewonlab867212a2014-10-22 20:13:38 -04002887 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002888 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002889 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002890 cmdStr += " -j"
2891 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002892 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002893 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002894 if handle:
2895 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002896 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002897 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002898 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002899 else:
2900 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002901 except AssertionError:
2902 main.log.exception( "" )
2903 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002904 except TypeError:
2905 main.log.exception( self.name + ": Object not as expected" )
2906 return None
andrewonlab867212a2014-10-22 20:13:38 -04002907 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002908 main.log.error( self.name + ": EOF exception found" )
2909 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002910 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002911 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002912 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002913 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002914
kelvin8ec71442015-01-15 16:57:00 -08002915 # Wrapper functions ****************
2916 # Wrapper functions use existing driver
2917 # functions and extends their use case.
2918 # For example, we may use the output of
2919 # a normal driver function, and parse it
2920 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002921
kelvin-onlabd3b64892015-01-20 13:26:24 -08002922 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002923 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002924 Description:
2925 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002926 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002927 try:
kelvin8ec71442015-01-15 16:57:00 -08002928 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002929 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002930 if intentsStr is None:
2931 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002932 # Convert to a dictionary
2933 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002934 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002935 for intent in intents:
2936 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002937 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002938 except TypeError:
2939 main.log.exception( self.name + ": Object not as expected" )
2940 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002941 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002942 main.log.error( self.name + ": EOF exception found" )
2943 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002944 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002945 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002946 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002947 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002948
You Wang3c276252016-09-21 15:21:36 -07002949 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002950 """
2951 Determine the number of flow rules for the given device id that are
2952 in the added state
You Wang3c276252016-09-21 15:21:36 -07002953 Params:
2954 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002955 """
2956 try:
You Wang3c276252016-09-21 15:21:36 -07002957 if core:
2958 cmdStr = "flows any " + str( deviceId ) + " | " +\
2959 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2960 else:
2961 cmdStr = "flows any " + str( deviceId ) + " | " +\
2962 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08002963 handle = self.lineCount( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002964 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002965 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002966 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002967 except AssertionError:
2968 main.log.exception( "" )
2969 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002970 except pexpect.EOF:
2971 main.log.error( self.name + ": EOF exception found" )
2972 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002973 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002974 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002975 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002976 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002977
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002978 def groupAddedCount( self, deviceId, core=False ):
2979 """
2980 Determine the number of group rules for the given device id that are
2981 in the added state
2982 Params:
2983 core: if True, only return the number of core groups added
2984 """
2985 try:
2986 if core:
2987 cmdStr = "groups any " + str( deviceId ) + " | " +\
2988 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2989 else:
2990 cmdStr = "groups any " + str( deviceId ) + " | " +\
2991 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08002992 handle = self.lineCount( cmdStr )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002993 assert handle is not None, "Error in sendline"
2994 assert "Command not found:" not in handle, handle
2995 return handle
2996 except AssertionError:
2997 main.log.exception( "" )
2998 return None
2999 except pexpect.EOF:
3000 main.log.error( self.name + ": EOF exception found" )
3001 main.log.error( self.name + ": " + self.handle.before )
3002 main.cleanAndExit()
3003 except Exception:
3004 main.log.exception( self.name + ": Uncaught exception!" )
3005 main.cleanAndExit()
3006
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003007 def addStaticRoute( self, subnet, intf):
3008 """
3009 Adds a static route to onos.
3010 Params:
3011 subnet: The subnet reaching through this route
3012 intf: The interface this route is reachable through
3013 """
3014 try:
3015 cmdStr = "route-add " + subnet + " " + intf
3016 handle = self.sendline( cmdStr )
3017 assert handle is not None, "Error in sendline"
3018 assert "Command not found:" not in handle, handle
3019 return handle
3020 except AssertionError:
3021 main.log.exception( "" )
3022 return None
3023 except pexpect.EOF:
3024 main.log.error( self.name + ": EOF exception found" )
3025 main.log.error( self.name + ": " + self.handle.before )
3026 main.cleanAndExit()
3027 except Exception:
3028 main.log.exception( self.name + ": Uncaught exception!" )
3029 main.cleanAndExit()
3030
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003031 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
3032 """
3033 Description:
3034 Check whether the number of groups for the given device id that
3035 are in ADDED state is bigger than minGroupCount.
3036 Required:
3037 * deviceId: device id to check the number of added group rules
3038 Optional:
3039 * minGroupCount: the number of groups to compare
3040 * core: if True, only check the number of core groups added
3041 * comparison: if 0, compare with greater than minFlowCount
3042 * if 1, compare with equal to minFlowCount
3043 Return:
3044 Returns the number of groups if it is bigger than minGroupCount,
3045 returns main.FALSE otherwise.
3046 """
3047 count = self.groupAddedCount( deviceId, core )
3048 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003049 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003050 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
3051
You Wangc02f3be2018-05-18 12:14:23 -07003052 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003053 """
3054 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07003055 deviceId: Id of the device from which we retrieve groups
3056 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003057 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003058 try:
You Wangc02f3be2018-05-18 12:14:23 -07003059 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
3060 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003061 assert handle is not None, "Error in sendline"
3062 assert "Command not found:" not in handle, handle
3063 return handle
3064 except AssertionError:
3065 main.log.exception( "" )
3066 return None
3067 except TypeError:
3068 main.log.exception( self.name + ": Object not as expected" )
3069 return None
3070 except pexpect.EOF:
3071 main.log.error( self.name + ": EOF exception found" )
3072 main.log.error( self.name + ": " + self.handle.before )
3073 main.cleanAndExit()
3074 except Exception:
3075 main.log.exception( self.name + ": Uncaught exception!" )
3076 main.cleanAndExit()
3077
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003078 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003079 """
3080 Description:
3081 Check whether the number of flow rules for the given device id that
3082 are in ADDED state is bigger than minFlowCount.
3083 Required:
3084 * deviceId: device id to check the number of added flow rules
3085 Optional:
3086 * minFlowCount: the number of flow rules to compare
3087 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003088 * comparison: if 0, compare with greater than minFlowCount
3089 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003090 Return:
3091 Returns the number of flow rules if it is bigger than minFlowCount,
3092 returns main.FALSE otherwise.
3093 """
3094 count = self.flowAddedCount( deviceId, core )
3095 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003096 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003097 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003098
kelvin-onlabd3b64892015-01-20 13:26:24 -08003099 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003100 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003101 Use 'devices' function to obtain list of all devices
3102 and parse the result to obtain a list of all device
3103 id's. Returns this list. Returns empty list if no
3104 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003105 List is ordered sequentially
3106
andrewonlab3e15ead2014-10-15 14:21:34 -04003107 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003108 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003109 the ids. By obtaining the list of device ids on the fly,
3110 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003111 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003112 try:
kelvin8ec71442015-01-15 16:57:00 -08003113 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003114 devicesStr = self.devices( jsonFormat=False )
3115 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003116
kelvin-onlabd3b64892015-01-20 13:26:24 -08003117 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003118 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003119 return idList
kelvin8ec71442015-01-15 16:57:00 -08003120
3121 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003122 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003123 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003124 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003125 # Split list further into arguments before and after string
3126 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003127 # append to idList
3128 for arg in tempList:
3129 idList.append( arg.split( "id=" )[ 1 ] )
3130 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003131
Jon Halld4d4b372015-01-28 16:02:41 -08003132 except TypeError:
3133 main.log.exception( self.name + ": Object not as expected" )
3134 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003135 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003136 main.log.error( self.name + ": EOF exception found" )
3137 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003138 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003139 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003140 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003141 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003142
kelvin-onlabd3b64892015-01-20 13:26:24 -08003143 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003144 """
andrewonlab7c211572014-10-15 16:45:20 -04003145 Uses 'nodes' function to obtain list of all nodes
3146 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003147 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003148 Returns:
3149 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003150 """
andrewonlab7c211572014-10-15 16:45:20 -04003151 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003152 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003153 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003154 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003155 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003156 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003157 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003158 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003159 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003160 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003161 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003162 except ( TypeError, ValueError ):
3163 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003164 return None
andrewonlab7c211572014-10-15 16:45:20 -04003165 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003166 main.log.error( self.name + ": EOF exception found" )
3167 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003168 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003169 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003170 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003171 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003172
kelvin-onlabd3b64892015-01-20 13:26:24 -08003173 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003174 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003175 Return the first device from the devices api whose 'id' contains 'dpid'
3176 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003177 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003178 try:
kelvin8ec71442015-01-15 16:57:00 -08003179 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003180 return None
3181 else:
kelvin8ec71442015-01-15 16:57:00 -08003182 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003183 rawDevices = self.devices()
3184 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003185 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003186 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003187 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3188 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003189 return device
3190 return None
Jon Hallc6793552016-01-19 14:18:37 -08003191 except ( TypeError, ValueError ):
3192 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003193 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003194 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003195 main.log.error( self.name + ": EOF exception found" )
3196 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003197 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003198 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003199 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003200 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003201
You Wang24139872016-05-03 11:48:47 -07003202 def getTopology( self, topologyOutput ):
3203 """
3204 Definition:
3205 Loads a json topology output
3206 Return:
3207 topology = current ONOS topology
3208 """
3209 import json
3210 try:
3211 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003212 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003213 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003214 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003215 except ( TypeError, ValueError ):
3216 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3217 return None
You Wang24139872016-05-03 11:48:47 -07003218 except pexpect.EOF:
3219 main.log.error( self.name + ": EOF exception found" )
3220 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003221 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003222 except Exception:
3223 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003224 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003225
Pier6a0c4de2018-03-18 16:01:30 -07003226 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003227 """
Jon Hallefbd9792015-03-05 16:11:36 -08003228 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003229 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003230 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003231
Flavio Castro82ee2f62016-06-07 15:04:12 -07003232 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003233 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003234 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003235 logLevel = level to log to.
3236 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003237
Jon Hallefbd9792015-03-05 16:11:36 -08003238 Returns: main.TRUE if the number of switches and links are correct,
3239 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003240 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003241 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003242 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003243 try:
You Wang13310252016-07-31 10:56:14 -07003244 summary = self.summary()
3245 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003246 except ( TypeError, ValueError ):
3247 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3248 return main.ERROR
3249 try:
3250 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003251 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003252 return main.ERROR
3253 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003254 # Is the number of switches is what we expected
3255 devices = topology.get( 'devices', False )
3256 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003257 nodes = summary.get( 'nodes', False )
3258 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003259 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003260 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003261 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003262 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003263 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3264 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003265 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003266 output = output + "The number of links and switches match "\
3267 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003268 result = main.TRUE
3269 else:
You Wang24139872016-05-03 11:48:47 -07003270 output = output + \
3271 "The number of links and switches does not match " + \
3272 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003273 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003274 output = output + "\n ONOS sees %i devices" % int( devices )
3275 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003276 if int( numolink ) > 0:
3277 output = output + "and %i links " % int( links )
3278 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003279 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003280 output = output + "and %i controllers " % int( nodes )
3281 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003282 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003283 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003284 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003285 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003286 else:
You Wang24139872016-05-03 11:48:47 -07003287 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003288 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003289 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003290 main.log.error( self.name + ": EOF exception found" )
3291 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003292 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003293 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003294 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003295 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003296
kelvin-onlabd3b64892015-01-20 13:26:24 -08003297 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003298 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003299 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003300 deviceId must be the id of a device as seen in the onos devices command
3301 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003302 role must be either master, standby, or none
3303
Jon Halle3f39ff2015-01-13 11:50:53 -08003304 Returns:
3305 main.TRUE or main.FALSE based on argument verification and
3306 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003307 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003308 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003309 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003310 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003311 cmdStr = "device-role " +\
3312 str( deviceId ) + " " +\
3313 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003314 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003315 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003316 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003317 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003318 if re.search( "Error", handle ):
3319 # end color output to escape any colours
3320 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003321 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003322 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003323 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003324 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003325 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003326 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003327 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003328 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003329 except AssertionError:
3330 main.log.exception( "" )
3331 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003332 except TypeError:
3333 main.log.exception( self.name + ": Object not as expected" )
3334 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003335 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003336 main.log.error( self.name + ": EOF exception found" )
3337 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003338 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003339 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003340 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003341 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003342
kelvin-onlabd3b64892015-01-20 13:26:24 -08003343 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003344 """
Jon Hall0dd09952018-04-19 09:59:11 -07003345 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003346 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003347 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003348 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003349 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003350 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003351 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003352 cmdStr += " -j"
3353 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003354 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003355 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003356 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003357 except AssertionError:
3358 main.log.exception( "" )
3359 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003360 except TypeError:
3361 main.log.exception( self.name + ": Object not as expected" )
3362 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003363 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003364 main.log.error( self.name + ": EOF exception found" )
3365 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003366 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003367 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003368 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003369 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003370
kelvin-onlabd3b64892015-01-20 13:26:24 -08003371 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003372 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003373 CLI command to get the current leader for the Election test application
3374 NOTE: Requires installation of the onos-app-election feature
3375 Returns: Node IP of the leader if one exists
3376 None if none exists
3377 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003378 """
Jon Hall94fd0472014-12-08 11:52:42 -08003379 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003380 cmdStr = "election-test-leader"
3381 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003382 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003383 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003384 # Leader
3385 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003386 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003387 nodeSearch = re.search( leaderPattern, response )
3388 if nodeSearch:
3389 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003390 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003391 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003392 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003393 # no leader
3394 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003395 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003396 nullSearch = re.search( nullPattern, response )
3397 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003398 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003399 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003400 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003401 # error
Jon Hall0e240372018-05-02 11:21:57 -07003402 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003403 ": " + "unexpected response" )
3404 main.log.error( repr( response ) )
3405 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003406 except AssertionError:
3407 main.log.exception( "" )
3408 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003409 except TypeError:
3410 main.log.exception( self.name + ": Object not as expected" )
3411 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003412 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003413 main.log.error( self.name + ": EOF exception found" )
3414 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003415 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003416 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003417 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003418 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003419
kelvin-onlabd3b64892015-01-20 13:26:24 -08003420 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003421 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003422 CLI command to run for leadership of 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
kelvin-onlab898a6c62015-01-16 14:13:53 -08003426 """
Jon Hall94fd0472014-12-08 11:52:42 -08003427 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003428 cmdStr = "election-test-run"
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 = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003434 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003435 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003436 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003437 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003438 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003439 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003440 # error
Jon Hall0e240372018-05-02 11:21:57 -07003441 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003442 ": " + "unexpected response" )
3443 main.log.error( repr( response ) )
3444 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003445 except AssertionError:
3446 main.log.exception( "" )
3447 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003448 except TypeError:
3449 main.log.exception( self.name + ": Object not as expected" )
3450 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003451 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003452 main.log.error( self.name + ": EOF exception found" )
3453 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003454 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003455 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003456 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003457 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003458
kelvin-onlabd3b64892015-01-20 13:26:24 -08003459 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003460 """
Jon Hall94fd0472014-12-08 11:52:42 -08003461 * CLI command to withdraw the local node from leadership election for
3462 * the Election test application.
3463 #NOTE: Requires installation of the onos-app-election feature
3464 Returns: Main.TRUE on success
3465 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003466 """
Jon Hall94fd0472014-12-08 11:52:42 -08003467 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003468 cmdStr = "election-test-withdraw"
3469 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003470 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003471 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003472 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003473 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003474 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003475 if re.search( successPattern, response ):
3476 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003477 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003478 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003479 # error
Jon Hall0e240372018-05-02 11:21:57 -07003480 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003481 self.name + ": " + "unexpected response" )
3482 main.log.error( repr( response ) )
3483 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003484 except AssertionError:
3485 main.log.exception( "" )
3486 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003487 except TypeError:
3488 main.log.exception( self.name + ": Object not as expected" )
3489 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003490 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003491 main.log.error( self.name + ": EOF exception found" )
3492 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003493 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003494 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003495 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003496 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003497
kelvin8ec71442015-01-15 16:57:00 -08003498 def getDevicePortsEnabledCount( self, dpid ):
3499 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003500 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003501 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003502 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003503 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003504 cmdStr = "onos:ports -e " + dpid + " | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003505 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003506 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003507 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003508 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003509 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003510 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003511 return output
Jon Hallc6793552016-01-19 14:18:37 -08003512 except AssertionError:
3513 main.log.exception( "" )
3514 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003515 except TypeError:
3516 main.log.exception( self.name + ": Object not as expected" )
3517 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003518 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003519 main.log.error( self.name + ": EOF exception found" )
3520 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003521 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003522 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003523 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003524 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003525
kelvin8ec71442015-01-15 16:57:00 -08003526 def getDeviceLinksActiveCount( self, dpid ):
3527 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003528 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003529 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003530 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003531 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003532 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003533 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003534 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003535 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003536 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003537 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003538 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003539 return output
Jon Hallc6793552016-01-19 14:18:37 -08003540 except AssertionError:
3541 main.log.exception( "" )
3542 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003543 except TypeError:
3544 main.log.exception( self.name + ": Object not as expected" )
3545 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003546 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003547 main.log.error( self.name + ": EOF exception found" )
3548 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003549 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003550 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003551 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003552 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003553
kelvin8ec71442015-01-15 16:57:00 -08003554 def getAllIntentIds( self ):
3555 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003556 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003557 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003558 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003559 cmdStr = "onos:intents | grep id="
3560 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003561 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003562 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003563 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003564 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003565 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003566 return output
Jon Hallc6793552016-01-19 14:18:37 -08003567 except AssertionError:
3568 main.log.exception( "" )
3569 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003570 except TypeError:
3571 main.log.exception( self.name + ": Object not as expected" )
3572 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003573 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003574 main.log.error( self.name + ": EOF exception found" )
3575 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003576 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003577 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003578 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003579 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003580
Jon Hall73509952015-02-24 16:42:56 -08003581 def intentSummary( self ):
3582 """
Jon Hallefbd9792015-03-05 16:11:36 -08003583 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003584 """
3585 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003586 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003587 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003588 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003589 states.append( intent.get( 'state', None ) )
3590 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003591 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003592 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003593 except ( TypeError, ValueError ):
3594 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003595 return None
3596 except pexpect.EOF:
3597 main.log.error( self.name + ": EOF exception found" )
3598 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003599 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003600 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003601 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003602 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003603
Jon Hall61282e32015-03-19 11:34:11 -07003604 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003605 """
3606 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003607 Optional argument:
3608 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003609 """
Jon Hall63604932015-02-26 17:09:50 -08003610 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003611 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003612 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003613 cmdStr += " -j"
3614 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003615 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003616 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003617 return output
Jon Hallc6793552016-01-19 14:18:37 -08003618 except AssertionError:
3619 main.log.exception( "" )
3620 return None
Jon Hall63604932015-02-26 17:09:50 -08003621 except TypeError:
3622 main.log.exception( self.name + ": Object not as expected" )
3623 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003624 except pexpect.EOF:
3625 main.log.error( self.name + ": EOF exception found" )
3626 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003627 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003628 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003629 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003630 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003631
acsmarsa4a4d1e2015-07-10 16:01:24 -07003632 def leaderCandidates( self, jsonFormat=True ):
3633 """
3634 Returns the output of the leaders -c command.
3635 Optional argument:
3636 * jsonFormat - boolean indicating if you want output in json
3637 """
3638 try:
3639 cmdStr = "onos:leaders -c"
3640 if jsonFormat:
3641 cmdStr += " -j"
3642 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003643 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003644 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003645 return output
Jon Hallc6793552016-01-19 14:18:37 -08003646 except AssertionError:
3647 main.log.exception( "" )
3648 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003649 except TypeError:
3650 main.log.exception( self.name + ": Object not as expected" )
3651 return None
3652 except pexpect.EOF:
3653 main.log.error( self.name + ": EOF exception found" )
3654 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003655 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003656 except Exception:
3657 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003658 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003659
Jon Hallc6793552016-01-19 14:18:37 -08003660 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003661 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003662 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003663 topic parameter and an empty list if the topic doesn't exist
3664 If no leader is elected leader in the returned list will be "none"
3665 Returns None if there is a type error processing the json object
3666 """
3667 try:
Jon Hall6e709752016-02-01 13:38:46 -08003668 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003669 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003670 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003671 assert "Command not found:" not in rawOutput, rawOutput
3672 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003673 results = []
3674 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003675 if dict[ "topic" ] == topic:
3676 leader = dict[ "leader" ]
3677 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003678 results.append( leader )
3679 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003680 return results
Jon Hallc6793552016-01-19 14:18:37 -08003681 except AssertionError:
3682 main.log.exception( "" )
3683 return None
3684 except ( TypeError, ValueError ):
3685 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003686 return None
3687 except pexpect.EOF:
3688 main.log.error( self.name + ": EOF exception found" )
3689 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003690 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003691 except Exception:
3692 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003693 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003694
Jon Hall61282e32015-03-19 11:34:11 -07003695 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003696 """
3697 Returns the output of the intent Pending map.
3698 """
Jon Hall63604932015-02-26 17:09:50 -08003699 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003700 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003701 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003702 cmdStr += " -j"
3703 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003704 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003705 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003706 return output
Jon Hallc6793552016-01-19 14:18:37 -08003707 except AssertionError:
3708 main.log.exception( "" )
3709 return None
Jon Hall63604932015-02-26 17:09:50 -08003710 except TypeError:
3711 main.log.exception( self.name + ": Object not as expected" )
3712 return None
3713 except pexpect.EOF:
3714 main.log.error( self.name + ": EOF exception found" )
3715 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003716 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003717 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003718 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003719 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003720
Jon Hall2c8959e2016-12-16 12:17:34 -08003721 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003722 """
3723 Returns the output of the raft partitions command for ONOS.
3724 """
Jon Hall61282e32015-03-19 11:34:11 -07003725 # Sample JSON
3726 # {
3727 # "leader": "tcp://10.128.30.11:7238",
3728 # "members": [
3729 # "tcp://10.128.30.11:7238",
3730 # "tcp://10.128.30.17:7238",
3731 # "tcp://10.128.30.13:7238",
3732 # ],
3733 # "name": "p1",
3734 # "term": 3
3735 # },
Jon Hall63604932015-02-26 17:09:50 -08003736 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003737 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003738 if candidates:
3739 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003740 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003741 cmdStr += " -j"
3742 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003743 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003744 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003745 return output
Jon Hallc6793552016-01-19 14:18:37 -08003746 except AssertionError:
3747 main.log.exception( "" )
3748 return None
Jon Hall63604932015-02-26 17:09:50 -08003749 except TypeError:
3750 main.log.exception( self.name + ": Object not as expected" )
3751 return None
3752 except pexpect.EOF:
3753 main.log.error( self.name + ": EOF exception found" )
3754 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003755 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003756 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003757 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003758 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003759
Jon Halle9f909e2016-09-23 10:43:12 -07003760 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003761 """
3762 Returns the output of the apps command for ONOS. This command lists
3763 information about installed ONOS applications
3764 """
3765 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003766 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003767 # "description":"ONOS OpenFlow protocol southbound providers",
3768 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003769 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003770 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003771 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003772 if summary:
3773 cmdStr += " -s"
3774 if active:
3775 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003776 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003777 cmdStr += " -j"
3778 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003779 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003780 assert "Command not found:" not in output, output
3781 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003782 return output
Jon Hallbe379602015-03-24 13:39:32 -07003783 # FIXME: look at specific exceptions/Errors
3784 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003785 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003786 return None
3787 except TypeError:
3788 main.log.exception( self.name + ": Object not as expected" )
3789 return None
3790 except pexpect.EOF:
3791 main.log.error( self.name + ": EOF exception found" )
3792 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003793 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003794 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003795 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003796 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003797
You Wangcdc51fe2018-08-12 17:14:56 -07003798 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003799 """
3800 Uses the onos:apps cli command to return the status of an application.
3801 Returns:
3802 "ACTIVE" - If app is installed and activated
3803 "INSTALLED" - If app is installed and deactivated
3804 "UNINSTALLED" - If app is not installed
3805 None - on error
3806 """
Jon Hall146f1522015-03-24 15:33:24 -07003807 try:
3808 if not isinstance( appName, types.StringType ):
3809 main.log.error( self.name + ".appStatus(): appName must be" +
3810 " a string" )
3811 return None
3812 output = self.apps( jsonFormat=True )
3813 appsJson = json.loads( output )
3814 state = None
3815 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003816 if appName == app.get( 'name' ):
3817 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003818 break
3819 if state == "ACTIVE" or state == "INSTALLED":
3820 return state
3821 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003822 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003823 return "UNINSTALLED"
3824 elif state:
3825 main.log.error( "Unexpected state from 'onos:apps': " +
3826 str( state ) )
3827 return state
Jon Hallc6793552016-01-19 14:18:37 -08003828 except ( TypeError, ValueError ):
3829 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003830 return None
3831 except pexpect.EOF:
3832 main.log.error( self.name + ": EOF exception found" )
3833 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003834 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003835 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003836 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003837 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003838
Jon Hallbe379602015-03-24 13:39:32 -07003839 def app( self, appName, option ):
3840 """
3841 Interacts with the app command for ONOS. This command manages
3842 application inventory.
3843 """
Jon Hallbe379602015-03-24 13:39:32 -07003844 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003845 # Validate argument types
3846 valid = True
3847 if not isinstance( appName, types.StringType ):
3848 main.log.error( self.name + ".app(): appName must be a " +
3849 "string" )
3850 valid = False
3851 if not isinstance( option, types.StringType ):
3852 main.log.error( self.name + ".app(): option must be a string" )
3853 valid = False
3854 if not valid:
3855 return main.FALSE
3856 # Validate Option
3857 option = option.lower()
3858 # NOTE: Install may become a valid option
3859 if option == "activate":
3860 pass
3861 elif option == "deactivate":
3862 pass
3863 elif option == "uninstall":
3864 pass
3865 else:
3866 # Invalid option
3867 main.log.error( "The ONOS app command argument only takes " +
3868 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003869 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003870 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003871 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003872 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003873 assert output is not None, "Error in sendline"
3874 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003875 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003876 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003877 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003878 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003879 elif "No such application" in output:
3880 main.log.error( "The application '" + appName +
3881 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003882 return main.FALSE
3883 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003884 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003885 str( output ) )
3886 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003887 elif "Unsupported command:" in output:
3888 main.log.error( "Incorrect command given to 'app': " +
3889 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003890 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003891 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003892 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003893 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003894 except AssertionError:
3895 main.log.exception( self.name + ": AssertionError exception found" )
3896 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003897 except TypeError:
3898 main.log.exception( self.name + ": Object not as expected" )
3899 return main.ERROR
3900 except pexpect.EOF:
3901 main.log.error( self.name + ": EOF exception found" )
3902 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003903 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003904 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003905 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003906 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003907
Jon Hallbd16b922015-03-26 17:53:15 -07003908 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003909 """
3910 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003911 appName is the hierarchical app name, not the feature name
3912 If check is True, method will check the status of the app after the
3913 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003914 Returns main.TRUE if the command was successfully sent
3915 main.FALSE if the cli responded with an error or given
3916 incorrect input
3917 """
3918 try:
3919 if not isinstance( appName, types.StringType ):
3920 main.log.error( self.name + ".activateApp(): appName must be" +
3921 " a string" )
3922 return main.FALSE
3923 status = self.appStatus( appName )
3924 if status == "INSTALLED":
3925 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003926 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003927 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003928 status = self.appStatus( appName )
3929 if status == "ACTIVE":
3930 return main.TRUE
3931 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003932 main.log.debug( "The state of application " +
3933 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003934 time.sleep( 1 )
3935 return main.FALSE
3936 else: # not 'check' or command didn't succeed
3937 return response
Jon Hall146f1522015-03-24 15:33:24 -07003938 elif status == "ACTIVE":
3939 return main.TRUE
3940 elif status == "UNINSTALLED":
3941 main.log.error( self.name + ": Tried to activate the " +
3942 "application '" + appName + "' which is not " +
3943 "installed." )
3944 else:
3945 main.log.error( "Unexpected return value from appStatus: " +
3946 str( status ) )
3947 return main.ERROR
3948 except TypeError:
3949 main.log.exception( self.name + ": Object not as expected" )
3950 return main.ERROR
3951 except pexpect.EOF:
3952 main.log.error( self.name + ": EOF exception found" )
3953 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003954 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003955 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003956 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003957 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003958
Jon Hallbd16b922015-03-26 17:53:15 -07003959 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003960 """
3961 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003962 appName is the hierarchical app name, not the feature name
3963 If check is True, method will check the status of the app after the
3964 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003965 Returns main.TRUE if the command was successfully sent
3966 main.FALSE if the cli responded with an error or given
3967 incorrect input
3968 """
3969 try:
3970 if not isinstance( appName, types.StringType ):
3971 main.log.error( self.name + ".deactivateApp(): appName must " +
3972 "be a string" )
3973 return main.FALSE
3974 status = self.appStatus( appName )
3975 if status == "INSTALLED":
3976 return main.TRUE
3977 elif status == "ACTIVE":
3978 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003979 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003980 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003981 status = self.appStatus( appName )
3982 if status == "INSTALLED":
3983 return main.TRUE
3984 else:
3985 time.sleep( 1 )
3986 return main.FALSE
3987 else: # not check or command didn't succeed
3988 return response
Jon Hall146f1522015-03-24 15:33:24 -07003989 elif status == "UNINSTALLED":
3990 main.log.warn( self.name + ": Tried to deactivate the " +
3991 "application '" + appName + "' which is not " +
3992 "installed." )
3993 return main.TRUE
3994 else:
3995 main.log.error( "Unexpected return value from appStatus: " +
3996 str( status ) )
3997 return main.ERROR
3998 except TypeError:
3999 main.log.exception( self.name + ": Object not as expected" )
4000 return main.ERROR
4001 except pexpect.EOF:
4002 main.log.error( self.name + ": EOF exception found" )
4003 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004004 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004005 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004006 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004007 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004008
Jon Hallbd16b922015-03-26 17:53:15 -07004009 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004010 """
4011 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004012 appName is the hierarchical app name, not the feature name
4013 If check is True, method will check the status of the app after the
4014 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004015 Returns main.TRUE if the command was successfully sent
4016 main.FALSE if the cli responded with an error or given
4017 incorrect input
4018 """
4019 # TODO: check with Thomas about the state machine for apps
4020 try:
4021 if not isinstance( appName, types.StringType ):
4022 main.log.error( self.name + ".uninstallApp(): appName must " +
4023 "be a string" )
4024 return main.FALSE
4025 status = self.appStatus( appName )
4026 if status == "INSTALLED":
4027 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004028 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004029 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004030 status = self.appStatus( appName )
4031 if status == "UNINSTALLED":
4032 return main.TRUE
4033 else:
4034 time.sleep( 1 )
4035 return main.FALSE
4036 else: # not check or command didn't succeed
4037 return response
Jon Hall146f1522015-03-24 15:33:24 -07004038 elif status == "ACTIVE":
4039 main.log.warn( self.name + ": Tried to uninstall the " +
4040 "application '" + appName + "' which is " +
4041 "currently active." )
4042 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004043 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004044 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004045 status = self.appStatus( appName )
4046 if status == "UNINSTALLED":
4047 return main.TRUE
4048 else:
4049 time.sleep( 1 )
4050 return main.FALSE
4051 else: # not check or command didn't succeed
4052 return response
Jon Hall146f1522015-03-24 15:33:24 -07004053 elif status == "UNINSTALLED":
4054 return main.TRUE
4055 else:
4056 main.log.error( "Unexpected return value from appStatus: " +
4057 str( status ) )
4058 return main.ERROR
4059 except TypeError:
4060 main.log.exception( self.name + ": Object not as expected" )
4061 return main.ERROR
4062 except pexpect.EOF:
4063 main.log.error( self.name + ": EOF exception found" )
4064 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004065 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004066 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004067 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004068 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004069
4070 def appIDs( self, jsonFormat=True ):
4071 """
4072 Show the mappings between app id and app names given by the 'app-ids'
4073 cli command
4074 """
4075 try:
4076 cmdStr = "app-ids"
4077 if jsonFormat:
4078 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004079 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004080 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004081 assert "Command not found:" not in output, output
4082 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004083 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004084 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004085 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004086 return None
4087 except TypeError:
4088 main.log.exception( self.name + ": Object not as expected" )
4089 return None
4090 except pexpect.EOF:
4091 main.log.error( self.name + ": EOF exception found" )
4092 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004093 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004094 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004095 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004096 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004097
4098 def appToIDCheck( self ):
4099 """
4100 This method will check that each application's ID listed in 'apps' is
4101 the same as the ID listed in 'app-ids'. The check will also check that
4102 there are no duplicate IDs issued. Note that an app ID should be
4103 a globaly unique numerical identifier for app/app-like features. Once
4104 an ID is registered, the ID is never freed up so that if an app is
4105 reinstalled it will have the same ID.
4106
4107 Returns: main.TRUE if the check passes and
4108 main.FALSE if the check fails or
4109 main.ERROR if there is some error in processing the test
4110 """
4111 try:
Jon Hall0e240372018-05-02 11:21:57 -07004112 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004113 rawJson = self.appIDs( jsonFormat=True )
4114 if rawJson:
4115 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004116 else:
Jon Hall0e240372018-05-02 11:21:57 -07004117 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4118 return main.FALSE
4119
4120 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004121 rawJson = self.apps( jsonFormat=True )
4122 if rawJson:
4123 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004124 else:
Jon Hallc6793552016-01-19 14:18:37 -08004125 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004126 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004127
Jon Hallbd16b922015-03-26 17:53:15 -07004128 result = main.TRUE
4129 for app in apps:
4130 appID = app.get( 'id' )
4131 if appID is None:
4132 main.log.error( "Error parsing app: " + str( app ) )
4133 result = main.FALSE
4134 appName = app.get( 'name' )
4135 if appName is None:
4136 main.log.error( "Error parsing app: " + str( app ) )
4137 result = main.FALSE
4138 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004139 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004140 if not current: # if ids doesn't have this id
4141 result = main.FALSE
4142 main.log.error( "'app-ids' does not have the ID for " +
4143 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004144 main.log.debug( "apps command returned: " + str( app ) +
4145 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004146 elif len( current ) > 1:
4147 # there is more than one app with this ID
4148 result = main.FALSE
4149 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004150 elif not current[ 0 ][ 'name' ] == appName:
4151 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004152 result = main.FALSE
4153 main.log.error( "'app-ids' has " + str( currentName ) +
4154 " registered under id:" + str( appID ) +
4155 " but 'apps' has " + str( appName ) )
4156 else:
4157 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004158
Jon Hallbd16b922015-03-26 17:53:15 -07004159 # now make sure that app-ids has no duplicates
4160 idsList = []
4161 namesList = []
4162 for item in ids:
4163 idsList.append( item[ 'id' ] )
4164 namesList.append( item[ 'name' ] )
4165 if len( idsList ) != len( set( idsList ) ) or\
4166 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004167 main.log.error( "'app-ids' has some duplicate entries: \n"
4168 + json.dumps( ids,
4169 sort_keys=True,
4170 indent=4,
4171 separators=( ',', ': ' ) ) )
4172 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004173 return result
Jon Hallc6793552016-01-19 14:18:37 -08004174 except ( TypeError, ValueError ):
4175 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004176 return main.ERROR
4177 except pexpect.EOF:
4178 main.log.error( self.name + ": EOF exception found" )
4179 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004180 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004181 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004182 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004183 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004184
Jon Hallfb760a02015-04-13 15:35:03 -07004185 def getCfg( self, component=None, propName=None, short=False,
4186 jsonFormat=True ):
4187 """
4188 Get configuration settings from onos cli
4189 Optional arguments:
4190 component - Optionally only list configurations for a specific
4191 component. If None, all components with configurations
4192 are displayed. Case Sensitive string.
4193 propName - If component is specified, propName option will show
4194 only this specific configuration from that component.
4195 Case Sensitive string.
4196 jsonFormat - Returns output as json. Note that this will override
4197 the short option
4198 short - Short, less verbose, version of configurations.
4199 This is overridden by the json option
4200 returns:
4201 Output from cli as a string or None on error
4202 """
4203 try:
4204 baseStr = "cfg"
4205 cmdStr = " get"
4206 componentStr = ""
4207 if component:
4208 componentStr += " " + component
4209 if propName:
4210 componentStr += " " + propName
4211 if jsonFormat:
4212 baseStr += " -j"
4213 elif short:
4214 baseStr += " -s"
4215 output = self.sendline( baseStr + cmdStr + componentStr )
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 return output
4220 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004221 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004222 return None
4223 except TypeError:
4224 main.log.exception( self.name + ": Object not as expected" )
4225 return None
4226 except pexpect.EOF:
4227 main.log.error( self.name + ": EOF exception found" )
4228 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004229 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004230 except Exception:
4231 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004232 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004233
4234 def setCfg( self, component, propName, value=None, check=True ):
4235 """
4236 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004237 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004238 component - The case sensitive name of the component whose
4239 property is to be set
4240 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004241 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004242 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004243 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004244 check - Boolean, Check whether the option was successfully set this
4245 only applies when a value is given.
4246 returns:
4247 main.TRUE on success or main.FALSE on failure. If check is False,
4248 will return main.TRUE unless there is an error
4249 """
4250 try:
4251 baseStr = "cfg"
4252 cmdStr = " set " + str( component ) + " " + str( propName )
4253 if value is not None:
4254 cmdStr += " " + str( value )
4255 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004256 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004257 assert "Command not found:" not in output, output
4258 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004259 if value and check:
4260 results = self.getCfg( component=str( component ),
4261 propName=str( propName ),
4262 jsonFormat=True )
4263 # Check if current value is what we just set
4264 try:
4265 jsonOutput = json.loads( results )
4266 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004267 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004268 main.log.exception( "Error parsing cfg output" )
4269 main.log.error( "output:" + repr( results ) )
4270 return main.FALSE
4271 if current == str( value ):
4272 return main.TRUE
4273 return main.FALSE
4274 return main.TRUE
4275 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004276 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004277 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004278 except ( TypeError, ValueError ):
4279 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004280 return main.FALSE
4281 except pexpect.EOF:
4282 main.log.error( self.name + ": EOF exception found" )
4283 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004284 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004285 except Exception:
4286 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004287 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004288
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004289 def distPrimitivesSend( self, cmd ):
4290 """
4291 Function to handle sending cli commands for the distributed primitives test app
4292
4293 This command will catch some exceptions and retry the command on some
4294 specific store exceptions.
4295
4296 Required arguments:
4297 cmd - The command to send to the cli
4298 returns:
4299 string containing the cli output
4300 None on Error
4301 """
4302 try:
4303 output = self.sendline( cmd )
4304 try:
4305 assert output is not None, "Error in sendline"
4306 # TODO: Maybe make this less hardcoded
4307 # ConsistentMap Exceptions
4308 assert "org.onosproject.store.service" not in output
4309 # Node not leader
4310 assert "java.lang.IllegalStateException" not in output
4311 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004312 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004313 "command: " + str( output ) )
4314 retryTime = 30 # Conservative time, given by Madan
4315 main.log.info( "Waiting " + str( retryTime ) +
4316 "seconds before retrying." )
4317 time.sleep( retryTime ) # Due to change in mastership
4318 output = self.sendline( cmd )
4319 assert output is not None, "Error in sendline"
4320 assert "Command not found:" not in output, output
4321 assert "Error executing command" not in output, output
4322 main.log.info( self.name + ": " + output )
4323 return output
4324 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004325 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004326 return None
4327 except TypeError:
4328 main.log.exception( self.name + ": Object not as expected" )
4329 return None
4330 except pexpect.EOF:
4331 main.log.error( self.name + ": EOF exception found" )
4332 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004333 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004334 except Exception:
4335 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004336 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004337
Jon Hall390696c2015-05-05 17:13:41 -07004338 def setTestAdd( self, setName, values ):
4339 """
4340 CLI command to add elements to a distributed set.
4341 Arguments:
4342 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004343 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004344 Example usages:
4345 setTestAdd( "set1", "a b c" )
4346 setTestAdd( "set2", "1" )
4347 returns:
4348 main.TRUE on success OR
4349 main.FALSE if elements were already in the set OR
4350 main.ERROR on error
4351 """
4352 try:
4353 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004354 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004355 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4356 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004357 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004358 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004359 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004360 return main.FALSE
4361 else:
4362 main.log.error( self.name + ": setTestAdd did not" +
4363 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004364 main.log.debug( self.name + " actual: " + repr( output ) )
4365 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004366 except TypeError:
4367 main.log.exception( self.name + ": Object not as expected" )
4368 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004369 except Exception:
4370 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004371 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004372
4373 def setTestRemove( self, setName, values, clear=False, retain=False ):
4374 """
4375 CLI command to remove elements from a distributed set.
4376 Required arguments:
4377 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004378 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004379 Optional arguments:
4380 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004381 retain - Retain only the given values. (intersection of the
4382 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004383 returns:
4384 main.TRUE on success OR
4385 main.FALSE if the set was not changed OR
4386 main.ERROR on error
4387 """
4388 try:
4389 cmdStr = "set-test-remove "
4390 if clear:
4391 cmdStr += "-c " + str( setName )
4392 elif retain:
4393 cmdStr += "-r " + str( setName ) + " " + str( values )
4394 else:
4395 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004396 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004397 if clear:
4398 pattern = "Set " + str( setName ) + " cleared"
4399 if re.search( pattern, output ):
4400 return main.TRUE
4401 elif retain:
4402 positivePattern = str( setName ) + " was pruned to contain " +\
4403 "only elements of set \[(.*)\]"
4404 negativePattern = str( setName ) + " was not changed by " +\
4405 "retaining only elements of the set " +\
4406 "\[(.*)\]"
4407 if re.search( positivePattern, output ):
4408 return main.TRUE
4409 elif re.search( negativePattern, output ):
4410 return main.FALSE
4411 else:
4412 positivePattern = "\[(.*)\] was removed from the set " +\
4413 str( setName )
4414 if ( len( values.split() ) == 1 ):
4415 negativePattern = "\[(.*)\] was not in set " +\
4416 str( setName )
4417 else:
4418 negativePattern = "No element of \[(.*)\] was in set " +\
4419 str( setName )
4420 if re.search( positivePattern, output ):
4421 return main.TRUE
4422 elif re.search( negativePattern, output ):
4423 return main.FALSE
4424 main.log.error( self.name + ": setTestRemove did not" +
4425 " match expected output" )
4426 main.log.debug( self.name + " expected: " + pattern )
4427 main.log.debug( self.name + " actual: " + repr( output ) )
4428 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004429 except TypeError:
4430 main.log.exception( self.name + ": Object not as expected" )
4431 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004432 except Exception:
4433 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004434 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004435
4436 def setTestGet( self, setName, values="" ):
4437 """
4438 CLI command to get the elements in a distributed set.
4439 Required arguments:
4440 setName - The name of the set to remove from.
4441 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004442 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004443 returns:
4444 main.ERROR on error OR
4445 A list of elements in the set if no optional arguments are
4446 supplied OR
4447 A tuple containing the list then:
4448 main.FALSE if the given values are not in the set OR
4449 main.TRUE if the given values are in the set OR
4450 """
4451 try:
4452 values = str( values ).strip()
4453 setName = str( setName ).strip()
4454 length = len( values.split() )
4455 containsCheck = None
4456 # Patterns to match
4457 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004458 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004459 containsTrue = "Set " + setName + " contains the value " + values
4460 containsFalse = "Set " + setName + " did not contain the value " +\
4461 values
4462 containsAllTrue = "Set " + setName + " contains the the subset " +\
4463 setPattern
4464 containsAllFalse = "Set " + setName + " did not contain the the" +\
4465 " subset " + setPattern
4466
4467 cmdStr = "set-test-get "
4468 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004469 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004470 if length == 0:
4471 match = re.search( pattern, output )
4472 else: # if given values
4473 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004474 patternTrue = pattern + "\r\n" + containsTrue
4475 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004476 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004477 patternTrue = pattern + "\r\n" + containsAllTrue
4478 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004479 matchTrue = re.search( patternTrue, output )
4480 matchFalse = re.search( patternFalse, output )
4481 if matchTrue:
4482 containsCheck = main.TRUE
4483 match = matchTrue
4484 elif matchFalse:
4485 containsCheck = main.FALSE
4486 match = matchFalse
4487 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004488 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004489 "expected output" )
4490 main.log.debug( self.name + " expected: " + pattern )
4491 main.log.debug( self.name + " actual: " + repr( output ) )
4492 match = None
4493 if match:
4494 setMatch = match.group( 1 )
4495 if setMatch == '':
4496 setList = []
4497 else:
4498 setList = setMatch.split( ", " )
4499 if length > 0:
4500 return ( setList, containsCheck )
4501 else:
4502 return setList
4503 else: # no match
4504 main.log.error( self.name + ": setTestGet did not" +
4505 " match expected output" )
4506 main.log.debug( self.name + " expected: " + pattern )
4507 main.log.debug( self.name + " actual: " + repr( output ) )
4508 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004509 except TypeError:
4510 main.log.exception( self.name + ": Object not as expected" )
4511 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004512 except Exception:
4513 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004514 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004515
4516 def setTestSize( self, setName ):
4517 """
4518 CLI command to get the elements in a distributed set.
4519 Required arguments:
4520 setName - The name of the set to remove from.
4521 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004522 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004523 None on error
4524 """
4525 try:
4526 # TODO: Should this check against the number of elements returned
4527 # and then return true/false based on that?
4528 setName = str( setName ).strip()
4529 # Patterns to match
4530 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004531 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004532 setPattern
4533 cmdStr = "set-test-get -s "
4534 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004535 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004536 if output:
4537 match = re.search( pattern, output )
4538 if match:
4539 setSize = int( match.group( 1 ) )
4540 setMatch = match.group( 2 )
4541 if len( setMatch.split() ) == setSize:
4542 main.log.info( "The size returned by " + self.name +
4543 " matches the number of elements in " +
4544 "the returned set" )
4545 else:
4546 main.log.error( "The size returned by " + self.name +
4547 " does not match the number of " +
4548 "elements in the returned set." )
4549 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004550 else: # no match
4551 main.log.error( self.name + ": setTestGet did not" +
4552 " match expected output" )
4553 main.log.debug( self.name + " expected: " + pattern )
4554 main.log.debug( self.name + " actual: " + repr( output ) )
4555 return None
Jon Hall390696c2015-05-05 17:13:41 -07004556 except TypeError:
4557 main.log.exception( self.name + ": Object not as expected" )
4558 return None
Jon Hall390696c2015-05-05 17:13:41 -07004559 except Exception:
4560 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004561 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004562
Jon Hall80daded2015-05-27 16:07:00 -07004563 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004564 """
4565 Command to list the various counters in the system.
4566 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004567 if jsonFormat, a string of the json object returned by the cli
4568 command
4569 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004570 None on error
4571 """
Jon Hall390696c2015-05-05 17:13:41 -07004572 try:
Jon Hall390696c2015-05-05 17:13:41 -07004573 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004574 if jsonFormat:
4575 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004576 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004577 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004578 assert "Command not found:" not in output, output
4579 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004580 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004581 return output
Jon Hall390696c2015-05-05 17:13:41 -07004582 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004583 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004584 return None
Jon Hall390696c2015-05-05 17:13:41 -07004585 except TypeError:
4586 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004587 return None
Jon Hall390696c2015-05-05 17:13:41 -07004588 except pexpect.EOF:
4589 main.log.error( self.name + ": EOF exception found" )
4590 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004591 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004592 except Exception:
4593 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004594 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004595
Jon Hall935db192016-04-19 00:22:04 -07004596 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004597 """
Jon Halle1a3b752015-07-22 13:02:46 -07004598 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004599 Required arguments:
4600 counter - The name of the counter to increment.
4601 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004602 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004603 returns:
4604 integer value of the counter or
4605 None on Error
4606 """
4607 try:
4608 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004609 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004610 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004611 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004612 if delta != 1:
4613 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004614 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004615 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004616 match = re.search( pattern, output )
4617 if match:
4618 return int( match.group( 1 ) )
4619 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004620 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004621 " match expected output." )
4622 main.log.debug( self.name + " expected: " + pattern )
4623 main.log.debug( self.name + " actual: " + repr( output ) )
4624 return None
Jon Hall390696c2015-05-05 17:13:41 -07004625 except TypeError:
4626 main.log.exception( self.name + ": Object not as expected" )
4627 return None
Jon Hall390696c2015-05-05 17:13:41 -07004628 except Exception:
4629 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004630 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004631
Jon Hall935db192016-04-19 00:22:04 -07004632 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004633 """
4634 CLI command to get a distributed counter then add a delta to it.
4635 Required arguments:
4636 counter - The name of the counter to increment.
4637 Optional arguments:
4638 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004639 returns:
4640 integer value of the counter or
4641 None on Error
4642 """
4643 try:
4644 counter = str( counter )
4645 delta = int( delta )
4646 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004647 cmdStr += counter
4648 if delta != 1:
4649 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004650 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004651 pattern = counter + " was updated to (-?\d+)"
4652 match = re.search( pattern, output )
4653 if match:
4654 return int( match.group( 1 ) )
4655 else:
4656 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4657 " match expected output." )
4658 main.log.debug( self.name + " expected: " + pattern )
4659 main.log.debug( self.name + " actual: " + repr( output ) )
4660 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004661 except TypeError:
4662 main.log.exception( self.name + ": Object not as expected" )
4663 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004664 except Exception:
4665 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004666 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004667
4668 def valueTestGet( self, valueName ):
4669 """
4670 CLI command to get the value of an atomic value.
4671 Required arguments:
4672 valueName - The name of the value to get.
4673 returns:
4674 string value of the value or
4675 None on Error
4676 """
4677 try:
4678 valueName = str( valueName )
4679 cmdStr = "value-test "
4680 operation = "get"
4681 cmdStr = "value-test {} {}".format( valueName,
4682 operation )
4683 output = self.distPrimitivesSend( cmdStr )
4684 pattern = "(\w+)"
4685 match = re.search( pattern, output )
4686 if match:
4687 return match.group( 1 )
4688 else:
4689 main.log.error( self.name + ": valueTestGet did not" +
4690 " match expected output." )
4691 main.log.debug( self.name + " expected: " + pattern )
4692 main.log.debug( self.name + " actual: " + repr( output ) )
4693 return None
4694 except TypeError:
4695 main.log.exception( self.name + ": Object not as expected" )
4696 return None
4697 except Exception:
4698 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004699 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004700
4701 def valueTestSet( self, valueName, newValue ):
4702 """
4703 CLI command to set the value of an atomic value.
4704 Required arguments:
4705 valueName - The name of the value to set.
4706 newValue - The value to assign to the given value.
4707 returns:
4708 main.TRUE on success or
4709 main.ERROR on Error
4710 """
4711 try:
4712 valueName = str( valueName )
4713 newValue = str( newValue )
4714 operation = "set"
4715 cmdStr = "value-test {} {} {}".format( valueName,
4716 operation,
4717 newValue )
4718 output = self.distPrimitivesSend( cmdStr )
4719 if output is not None:
4720 return main.TRUE
4721 else:
4722 return main.ERROR
4723 except TypeError:
4724 main.log.exception( self.name + ": Object not as expected" )
4725 return main.ERROR
4726 except Exception:
4727 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004728 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004729
4730 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4731 """
4732 CLI command to compareAndSet the value of an atomic value.
4733 Required arguments:
4734 valueName - The name of the value.
4735 oldValue - Compare the current value of the atomic value to this
4736 newValue - If the value equals oldValue, set the value to newValue
4737 returns:
4738 main.TRUE on success or
4739 main.FALSE on failure or
4740 main.ERROR on Error
4741 """
4742 try:
4743 valueName = str( valueName )
4744 oldValue = str( oldValue )
4745 newValue = str( newValue )
4746 operation = "compareAndSet"
4747 cmdStr = "value-test {} {} {} {}".format( valueName,
4748 operation,
4749 oldValue,
4750 newValue )
4751 output = self.distPrimitivesSend( cmdStr )
4752 pattern = "(\w+)"
4753 match = re.search( pattern, output )
4754 if match:
4755 result = match.group( 1 )
4756 if result == "true":
4757 return main.TRUE
4758 elif result == "false":
4759 return main.FALSE
4760 else:
4761 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4762 " match expected output." )
4763 main.log.debug( self.name + " expected: " + pattern )
4764 main.log.debug( self.name + " actual: " + repr( output ) )
4765 return main.ERROR
4766 except TypeError:
4767 main.log.exception( self.name + ": Object not as expected" )
4768 return main.ERROR
4769 except Exception:
4770 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004771 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004772
4773 def valueTestGetAndSet( self, valueName, newValue ):
4774 """
4775 CLI command to getAndSet the value of an atomic value.
4776 Required arguments:
4777 valueName - The name of the value to get.
4778 newValue - The value to assign to the given value
4779 returns:
4780 string value of the value or
4781 None on Error
4782 """
4783 try:
4784 valueName = str( valueName )
4785 cmdStr = "value-test "
4786 operation = "getAndSet"
4787 cmdStr += valueName + " " + operation
4788 cmdStr = "value-test {} {} {}".format( valueName,
4789 operation,
4790 newValue )
4791 output = self.distPrimitivesSend( cmdStr )
4792 pattern = "(\w+)"
4793 match = re.search( pattern, output )
4794 if match:
4795 return match.group( 1 )
4796 else:
4797 main.log.error( self.name + ": valueTestGetAndSet did not" +
4798 " match expected output." )
4799 main.log.debug( self.name + " expected: " + pattern )
4800 main.log.debug( self.name + " actual: " + repr( output ) )
4801 return None
4802 except TypeError:
4803 main.log.exception( self.name + ": Object not as expected" )
4804 return None
4805 except Exception:
4806 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004807 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004808
4809 def valueTestDestroy( self, valueName ):
4810 """
4811 CLI command to destroy an atomic value.
4812 Required arguments:
4813 valueName - The name of the value to destroy.
4814 returns:
4815 main.TRUE on success or
4816 main.ERROR on Error
4817 """
4818 try:
4819 valueName = str( valueName )
4820 cmdStr = "value-test "
4821 operation = "destroy"
4822 cmdStr += valueName + " " + operation
4823 output = self.distPrimitivesSend( cmdStr )
4824 if output is not None:
4825 return main.TRUE
4826 else:
4827 return main.ERROR
4828 except TypeError:
4829 main.log.exception( self.name + ": Object not as expected" )
4830 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004831 except Exception:
4832 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004833 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004834
YPZhangfebf7302016-05-24 16:45:56 -07004835 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004836 """
4837 Description: Execute summary command in onos
4838 Returns: json object ( summary -j ), returns main.FALSE if there is
4839 no output
4840
4841 """
4842 try:
4843 cmdStr = "summary"
4844 if jsonFormat:
4845 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004846 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004847 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004848 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004849 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004850 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004851 if not handle:
4852 main.log.error( self.name + ": There is no output in " +
4853 "summary command" )
4854 return main.FALSE
4855 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004856 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004857 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004858 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004859 except TypeError:
4860 main.log.exception( self.name + ": Object not as expected" )
4861 return None
4862 except pexpect.EOF:
4863 main.log.error( self.name + ": EOF exception found" )
4864 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004865 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004866 except Exception:
4867 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004868 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004869
Jon Hall935db192016-04-19 00:22:04 -07004870 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004871 """
4872 CLI command to get the value of a key in a consistent map using
4873 transactions. This a test function and can only get keys from the
4874 test map hard coded into the cli command
4875 Required arguments:
4876 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004877 returns:
4878 The string value of the key or
4879 None on Error
4880 """
4881 try:
4882 keyName = str( keyName )
4883 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004884 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004885 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004886 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4887 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004888 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004889 return None
4890 else:
4891 match = re.search( pattern, output )
4892 if match:
4893 return match.groupdict()[ 'value' ]
4894 else:
4895 main.log.error( self.name + ": transactionlMapGet did not" +
4896 " match expected output." )
4897 main.log.debug( self.name + " expected: " + pattern )
4898 main.log.debug( self.name + " actual: " + repr( output ) )
4899 return None
4900 except TypeError:
4901 main.log.exception( self.name + ": Object not as expected" )
4902 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004903 except Exception:
4904 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004905 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004906
Jon Hall935db192016-04-19 00:22:04 -07004907 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004908 """
4909 CLI command to put a value into 'numKeys' number of keys in a
4910 consistent map using transactions. This a test function and can only
4911 put into keys named 'Key#' of the test map hard coded into the cli command
4912 Required arguments:
4913 numKeys - Number of keys to add the value to
4914 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004915 returns:
4916 A dictionary whose keys are the name of the keys put into the map
4917 and the values of the keys are dictionaries whose key-values are
4918 'value': value put into map and optionaly
4919 'oldValue': Previous value in the key or
4920 None on Error
4921
4922 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004923 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4924 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004925 """
4926 try:
4927 numKeys = str( numKeys )
4928 value = str( value )
4929 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004930 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004931 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004932 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4933 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4934 results = {}
4935 for line in output.splitlines():
4936 new = re.search( newPattern, line )
4937 updated = re.search( updatedPattern, line )
4938 if new:
4939 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4940 elif updated:
4941 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004942 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004943 else:
4944 main.log.error( self.name + ": transactionlMapGet did not" +
4945 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004946 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4947 newPattern,
4948 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004949 main.log.debug( self.name + " actual: " + repr( output ) )
4950 return results
Jon Hall0e240372018-05-02 11:21:57 -07004951 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004952 main.log.exception( self.name + ": Object not as expected" )
4953 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004954 except Exception:
4955 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004956 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004957
acsmarsdaea66c2015-09-03 11:44:06 -07004958 def maps( self, jsonFormat=True ):
4959 """
4960 Description: Returns result of onos:maps
4961 Optional:
4962 * jsonFormat: enable json formatting of output
4963 """
4964 try:
4965 cmdStr = "maps"
4966 if jsonFormat:
4967 cmdStr += " -j"
4968 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004969 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004970 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004971 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004972 except AssertionError:
4973 main.log.exception( "" )
4974 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004975 except TypeError:
4976 main.log.exception( self.name + ": Object not as expected" )
4977 return None
4978 except pexpect.EOF:
4979 main.log.error( self.name + ": EOF exception found" )
4980 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004981 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004982 except Exception:
4983 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004984 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004985
4986 def getSwController( self, uri, jsonFormat=True ):
4987 """
4988 Descrition: Gets the controller information from the device
4989 """
4990 try:
4991 cmd = "device-controllers "
4992 if jsonFormat:
4993 cmd += "-j "
4994 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004995 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004996 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004997 return response
Jon Hallc6793552016-01-19 14:18:37 -08004998 except AssertionError:
4999 main.log.exception( "" )
5000 return None
GlennRC050596c2015-11-18 17:06:41 -08005001 except TypeError:
5002 main.log.exception( self.name + ": Object not as expected" )
5003 return None
5004 except pexpect.EOF:
5005 main.log.error( self.name + ": EOF exception found" )
5006 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005007 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005008 except Exception:
5009 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005010 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005011
5012 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
5013 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005014 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08005015
5016 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005017 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08005018 ip - String or List: The ip address of the controller.
5019 This parameter can be formed in a couple of different ways.
5020 VALID:
5021 10.0.0.1 - just the ip address
5022 tcp:10.0.0.1 - the protocol and the ip address
5023 tcp:10.0.0.1:6653 - the protocol and port can be specified,
5024 so that you can add controllers with different
5025 protocols and ports
5026 INVALID:
5027 10.0.0.1:6653 - this is not supported by ONOS
5028
5029 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
5030 port - The port number.
5031 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
5032
5033 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
5034 """
5035 try:
5036 cmd = "device-setcontrollers"
5037
5038 if jsonFormat:
5039 cmd += " -j"
5040 cmd += " " + uri
5041 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005042 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08005043 for item in ip:
5044 if ":" in item:
5045 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005046 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08005047 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005048 elif "." in sitem[ 1 ]:
5049 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08005050 else:
5051 main.log.error( "Malformed entry: " + item )
5052 raise TypeError
5053 else:
5054 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08005055 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07005056 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005057 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005058 if "Error" in response:
5059 main.log.error( response )
5060 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005061 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005062 except AssertionError:
5063 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005064 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005065 except TypeError:
5066 main.log.exception( self.name + ": Object not as expected" )
5067 return main.FALSE
5068 except pexpect.EOF:
5069 main.log.error( self.name + ": EOF exception found" )
5070 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005071 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005072 except Exception:
5073 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005074 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005075
5076 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005077 '''
GlennRC20fc6522015-12-23 23:26:57 -08005078 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005079 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005080 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005081 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005082 Returns:
5083 Returns main.FALSE if an exception is thrown or an error is present
5084 in the response. Otherwise, returns main.TRUE.
5085 NOTE:
5086 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005087 '''
GlennRC20fc6522015-12-23 23:26:57 -08005088 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005089 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005090 deviceStr = device
5091 device = []
5092 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005093
5094 for d in device:
5095 time.sleep( 1 )
5096 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005097 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005098 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005099 if "Error" in response:
5100 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5101 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005102 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005103 except AssertionError:
5104 main.log.exception( "" )
5105 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005106 except TypeError:
5107 main.log.exception( self.name + ": Object not as expected" )
5108 return main.FALSE
5109 except pexpect.EOF:
5110 main.log.error( self.name + ": EOF exception found" )
5111 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005112 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005113 except Exception:
5114 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005115 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005116
5117 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005118 '''
GlennRC20fc6522015-12-23 23:26:57 -08005119 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005120 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005121 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005122 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005123 Returns:
5124 Returns main.FALSE if an exception is thrown or an error is present
5125 in the response. Otherwise, returns main.TRUE.
5126 NOTE:
5127 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005128 '''
GlennRC20fc6522015-12-23 23:26:57 -08005129 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005130 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005131 host = list( host )
5132
5133 for h in host:
5134 time.sleep( 1 )
5135 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005136 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005137 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005138 if "Error" in response:
5139 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5140 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005141 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005142 except AssertionError:
5143 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005144 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005145 except TypeError:
5146 main.log.exception( self.name + ": Object not as expected" )
5147 return main.FALSE
5148 except pexpect.EOF:
5149 main.log.error( self.name + ": EOF exception found" )
5150 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005151 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005152 except Exception:
5153 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005154 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005155
YPZhangfebf7302016-05-24 16:45:56 -07005156 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005157 '''
GlennRCed771242016-01-13 17:02:47 -08005158 Description:
5159 Bring link down or up in the null-provider.
5160 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005161 begin - (string) One end of a device or switch.
5162 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005163 returns:
5164 main.TRUE if no exceptions were thrown and no Errors are
5165 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005166 '''
GlennRCed771242016-01-13 17:02:47 -08005167 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005168 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005169 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005170 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005171 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005172 if "Error" in response or "Failure" in response:
5173 main.log.error( response )
5174 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005175 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005176 except AssertionError:
5177 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005178 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005179 except TypeError:
5180 main.log.exception( self.name + ": Object not as expected" )
5181 return main.FALSE
5182 except pexpect.EOF:
5183 main.log.error( self.name + ": EOF exception found" )
5184 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005185 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005186 except Exception:
5187 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005188 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005189
Jon Hall2c8959e2016-12-16 12:17:34 -08005190 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005191 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005192 Description:
5193 Changes the state of port in an OF switch by means of the
5194 PORTSTATUS OF messages.
5195 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005196 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5197 port - (string) target port in the device. Ex: '2'
5198 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005199 returns:
5200 main.TRUE if no exceptions were thrown and no Errors are
5201 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005202 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005203 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005204 state = state.lower()
5205 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005206 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005207 response = self.sendline( cmd, showResponse=True )
5208 assert response is not None, "Error in sendline"
5209 assert "Command not found:" not in response, response
5210 if "Error" in response or "Failure" in response:
5211 main.log.error( response )
5212 return main.FALSE
5213 return main.TRUE
5214 except AssertionError:
5215 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005216 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005217 except TypeError:
5218 main.log.exception( self.name + ": Object not as expected" )
5219 return main.FALSE
5220 except pexpect.EOF:
5221 main.log.error( self.name + ": EOF exception found" )
5222 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005223 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005224 except Exception:
5225 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005226 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005227
5228 def logSet( self, level="INFO", app="org.onosproject" ):
5229 """
5230 Set the logging level to lvl for a specific app
5231 returns main.TRUE on success
5232 returns main.FALSE if Error occurred
5233 if noExit is True, TestON will not exit, but clean up
5234 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5235 Level defaults to INFO
5236 """
5237 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005238 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -08005239 self.handle.expect( self.karafPrompt )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005240
5241 response = self.handle.before
5242 if re.search( "Error", response ):
5243 return main.FALSE
5244 return main.TRUE
5245 except pexpect.TIMEOUT:
5246 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005247 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005248 except pexpect.EOF:
5249 main.log.error( self.name + ": EOF exception found" )
5250 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005251 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005252 except Exception:
5253 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005254 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005255
5256 def getGraphDict( self, timeout=60, includeHost=False ):
5257 """
5258 Return a dictionary which describes the latest network topology data as a
5259 graph.
5260 An example of the dictionary:
5261 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5262 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5263 Each vertex should at least have an 'edges' attribute which describes the
5264 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005265 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005266 list of attributes.
5267 An example of the edges dictionary:
5268 'edges': { vertex2: { 'port': ..., 'weight': ... },
5269 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005270 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005271 in topology data.
5272 """
5273 graphDict = {}
5274 try:
5275 links = self.links()
5276 links = json.loads( links )
5277 devices = self.devices()
5278 devices = json.loads( devices )
5279 idToDevice = {}
5280 for device in devices:
5281 idToDevice[ device[ 'id' ] ] = device
5282 if includeHost:
5283 hosts = self.hosts()
5284 # FIXME: support 'includeHost' argument
5285 for link in links:
5286 nodeA = link[ 'src' ][ 'device' ]
5287 nodeB = link[ 'dst' ][ 'device' ]
5288 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005289 if nodeA not in graphDict.keys():
5290 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005291 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005292 'type': idToDevice[ nodeA ][ 'type' ],
5293 'available': idToDevice[ nodeA ][ 'available' ],
5294 'role': idToDevice[ nodeA ][ 'role' ],
5295 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5296 'hw': idToDevice[ nodeA ][ 'hw' ],
5297 'sw': idToDevice[ nodeA ][ 'sw' ],
5298 'serial': idToDevice[ nodeA ][ 'serial' ],
5299 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005300 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005301 else:
5302 # Assert nodeB is not connected to any current links of nodeA
5303 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005304 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5305 'type': link[ 'type' ],
5306 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005307 return graphDict
5308 except ( TypeError, ValueError ):
5309 main.log.exception( self.name + ": Object not as expected" )
5310 return None
5311 except KeyError:
5312 main.log.exception( self.name + ": KeyError exception found" )
5313 return None
5314 except AssertionError:
5315 main.log.exception( self.name + ": AssertionError exception found" )
5316 return None
5317 except pexpect.EOF:
5318 main.log.error( self.name + ": EOF exception found" )
5319 main.log.error( self.name + ": " + self.handle.before )
5320 return None
5321 except Exception:
5322 main.log.exception( self.name + ": Uncaught exception!" )
5323 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005324
5325 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005326 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005327 Send command to check intent-perf summary
5328 Returns: dictionary for intent-perf summary
5329 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005330 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005331 cmd = "intent-perf -s"
5332 respDic = {}
5333 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005334 assert resp is not None, "Error in sendline"
5335 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005336 try:
5337 # Generate the dictionary to return
5338 for l in resp.split( "\n" ):
5339 # Delete any white space in line
5340 temp = re.sub( r'\s+', '', l )
5341 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005342 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005343
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005344 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005345 main.log.exception( self.name + ": Object not as expected" )
5346 return None
5347 except KeyError:
5348 main.log.exception( self.name + ": KeyError exception found" )
5349 return None
5350 except AssertionError:
5351 main.log.exception( self.name + ": AssertionError exception found" )
5352 return None
5353 except pexpect.EOF:
5354 main.log.error( self.name + ": EOF exception found" )
5355 main.log.error( self.name + ": " + self.handle.before )
5356 return None
5357 except Exception:
5358 main.log.exception( self.name + ": Uncaught exception!" )
5359 return None
5360 return respDic
5361
Chiyu Chengec63bde2016-11-17 18:11:36 -08005362 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005363 """
5364 Searches the latest ONOS log file for the given search term and
5365 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005366
chengchiyu08303a02016-09-08 17:40:26 -07005367 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005368 searchTerm:
5369 The string to grep from the ONOS log.
5370 startLine:
5371 The term that decides which line is the start to search the searchTerm in
5372 the karaf log. For now, startTerm only works in 'first' mode.
5373 logNum:
5374 In some extreme cases, one karaf log is not big enough to contain all the
5375 information.Because of this, search mutiply logs is necessary to capture
5376 the right result. logNum is the number of karaf logs that we need to search
5377 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005378 mode:
5379 all: return all the strings that contain the search term
5380 last: return the last string that contains the search term
5381 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005382 num: return the number of times that the searchTerm appears in the log
5383 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005384 """
5385 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005386 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005387 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005388 logPath = '/opt/onos/log/karaf.log.'
5389 logPaths = '/opt/onos/log/karaf.log'
5390 for i in range( 1, logNum ):
5391 logPaths = logPath + str( i ) + " " + logPaths
5392 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005393 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005394 # 100000000 is just a extreme large number to make sure this function can
5395 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005396 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005397 if mode == 'all':
5398 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005399 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005400 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005401 elif mode == 'first':
5402 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5403 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005404 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005405 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005406 return num
You Wang6d301d42017-04-21 10:49:33 -07005407 elif mode == 'total':
Jon Halld5a94fb2018-11-13 14:32:23 -08005408 totalLines = self.lineCount( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005409 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005410 else:
5411 main.log.error( self.name + " unsupported mode" )
5412 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005413 before = self.sendline( cmd )
5414 before = before.splitlines()
5415 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005416 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005417 return returnLines
5418 except AssertionError:
5419 main.log.error( self.name + " searchTerm is not string type" )
5420 return None
5421 except pexpect.EOF:
5422 main.log.error( self.name + ": EOF exception found" )
5423 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005424 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005425 except pexpect.TIMEOUT:
5426 main.log.error( self.name + ": TIMEOUT exception found" )
5427 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005428 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005429 except Exception:
5430 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005431 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005432
5433 def vplsShow( self, jsonFormat=True ):
5434 """
5435 Description: Returns result of onos:vpls show, which should list the
5436 configured VPLS networks and the assigned interfaces.
5437 Optional:
5438 * jsonFormat: enable json formatting of output
5439 Returns:
5440 The output of the command or None on error.
5441 """
5442 try:
5443 cmdStr = "vpls show"
5444 if jsonFormat:
5445 raise NotImplementedError
5446 cmdStr += " -j"
5447 handle = self.sendline( cmdStr )
5448 assert handle is not None, "Error in sendline"
5449 assert "Command not found:" not in handle, handle
5450 return handle
5451 except AssertionError:
5452 main.log.exception( "" )
5453 return None
5454 except TypeError:
5455 main.log.exception( self.name + ": Object not as expected" )
5456 return None
5457 except pexpect.EOF:
5458 main.log.error( self.name + ": EOF exception found" )
5459 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005460 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005461 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005462 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005463 return None
5464 except Exception:
5465 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005466 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005467
5468 def parseVplsShow( self ):
5469 """
5470 Parse the cli output of 'vpls show' into json output. This is required
5471 as there is currently no json output available.
5472 """
5473 try:
5474 output = []
5475 raw = self.vplsShow( jsonFormat=False )
5476 namePat = "VPLS name: (?P<name>\w+)"
5477 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5478 encapPat = "Encapsulation: (?P<encap>\w+)"
5479 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5480 mIter = re.finditer( pattern, raw )
5481 for match in mIter:
5482 item = {}
5483 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005484 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005485 if ifaces == [ "" ]:
5486 ifaces = []
5487 item[ 'interfaces' ] = ifaces
5488 encap = match.group( 'encap' )
5489 if encap != 'NONE':
5490 item[ 'encapsulation' ] = encap.lower()
5491 output.append( item )
5492 return output
5493 except Exception:
5494 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005495 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005496
5497 def vplsList( self, jsonFormat=True ):
5498 """
5499 Description: Returns result of onos:vpls list, which should list the
5500 configured VPLS networks.
5501 Optional:
5502 * jsonFormat: enable json formatting of output
5503 """
5504 try:
5505 cmdStr = "vpls list"
5506 if jsonFormat:
5507 raise NotImplementedError
5508 cmdStr += " -j"
5509 handle = self.sendline( cmdStr )
5510 assert handle is not None, "Error in sendline"
5511 assert "Command not found:" not in handle, handle
5512 return handle
5513 except AssertionError:
5514 main.log.exception( "" )
5515 return None
5516 except TypeError:
5517 main.log.exception( self.name + ": Object not as expected" )
5518 return None
5519 except pexpect.EOF:
5520 main.log.error( self.name + ": EOF exception found" )
5521 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005522 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005523 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005524 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005525 return None
5526 except Exception:
5527 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005528 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005529
5530 def vplsCreate( self, network ):
5531 """
5532 CLI command to create a new VPLS network.
5533 Required arguments:
5534 network - String name of the network to create.
5535 returns:
5536 main.TRUE on success and main.FALSE on failure
5537 """
5538 try:
5539 network = str( network )
5540 cmdStr = "vpls create "
5541 cmdStr += network
5542 output = self.sendline( cmdStr )
5543 assert output is not None, "Error in sendline"
5544 assert "Command not found:" not in output, output
5545 assert "Error executing command" not in output, output
5546 assert "VPLS already exists:" not in output, output
5547 return main.TRUE
5548 except AssertionError:
5549 main.log.exception( "" )
5550 return main.FALSE
5551 except TypeError:
5552 main.log.exception( self.name + ": Object not as expected" )
5553 return main.FALSE
5554 except pexpect.EOF:
5555 main.log.error( self.name + ": EOF exception found" )
5556 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005557 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005558 except Exception:
5559 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005560 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005561
5562 def vplsDelete( self, network ):
5563 """
5564 CLI command to delete a VPLS network.
5565 Required arguments:
5566 network - Name of the network to delete.
5567 returns:
5568 main.TRUE on success and main.FALSE on failure
5569 """
5570 try:
5571 network = str( network )
5572 cmdStr = "vpls delete "
5573 cmdStr += network
5574 output = self.sendline( cmdStr )
5575 assert output is not None, "Error in sendline"
5576 assert "Command not found:" not in output, output
5577 assert "Error executing command" not in output, output
5578 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005579 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005580 return main.TRUE
5581 except AssertionError:
5582 main.log.exception( "" )
5583 return main.FALSE
5584 except TypeError:
5585 main.log.exception( self.name + ": Object not as expected" )
5586 return main.FALSE
5587 except pexpect.EOF:
5588 main.log.error( self.name + ": EOF exception found" )
5589 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005590 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005591 except Exception:
5592 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005593 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005594
5595 def vplsAddIface( self, network, iface ):
5596 """
5597 CLI command to add an interface to a VPLS network.
5598 Required arguments:
5599 network - Name of the network to add the interface to.
5600 iface - The ONOS name for an interface.
5601 returns:
5602 main.TRUE on success and main.FALSE on failure
5603 """
5604 try:
5605 network = str( network )
5606 iface = str( iface )
5607 cmdStr = "vpls add-if "
5608 cmdStr += network + " " + iface
5609 output = self.sendline( cmdStr )
5610 assert output is not None, "Error in sendline"
5611 assert "Command not found:" not in output, output
5612 assert "Error executing command" not in output, output
5613 assert "already associated to network" not in output, output
5614 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005615 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005616 return main.TRUE
5617 except AssertionError:
5618 main.log.exception( "" )
5619 return main.FALSE
5620 except TypeError:
5621 main.log.exception( self.name + ": Object not as expected" )
5622 return main.FALSE
5623 except pexpect.EOF:
5624 main.log.error( self.name + ": EOF exception found" )
5625 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005626 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005627 except Exception:
5628 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005629 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005630
5631 def vplsRemIface( self, network, iface ):
5632 """
5633 CLI command to remove an interface from a VPLS network.
5634 Required arguments:
5635 network - Name of the network to remove the interface from.
5636 iface - Name of the interface to remove.
5637 returns:
5638 main.TRUE on success and main.FALSE on failure
5639 """
5640 try:
5641 iface = str( iface )
5642 cmdStr = "vpls rem-if "
5643 cmdStr += network + " " + iface
5644 output = self.sendline( cmdStr )
5645 assert output is not None, "Error in sendline"
5646 assert "Command not found:" not in output, output
5647 assert "Error executing command" not in output, output
5648 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005649 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005650 return main.TRUE
5651 except AssertionError:
5652 main.log.exception( "" )
5653 return main.FALSE
5654 except TypeError:
5655 main.log.exception( self.name + ": Object not as expected" )
5656 return main.FALSE
5657 except pexpect.EOF:
5658 main.log.error( self.name + ": EOF exception found" )
5659 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005660 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005661 except Exception:
5662 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005663 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005664
5665 def vplsClean( self ):
5666 """
5667 Description: Clears the VPLS app configuration.
5668 Returns: main.TRUE on success and main.FALSE on failure
5669 """
5670 try:
5671 cmdStr = "vpls clean"
5672 handle = self.sendline( cmdStr )
5673 assert handle is not None, "Error in sendline"
5674 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005675 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005676 return handle
5677 except AssertionError:
5678 main.log.exception( "" )
5679 return main.FALSE
5680 except TypeError:
5681 main.log.exception( self.name + ": Object not as expected" )
5682 return main.FALSE
5683 except pexpect.EOF:
5684 main.log.error( self.name + ": EOF exception found" )
5685 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005686 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005687 except Exception:
5688 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005689 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005690
5691 def vplsSetEncap( self, network, encapType ):
5692 """
5693 CLI command to add an interface to a VPLS network.
5694 Required arguments:
5695 network - Name of the network to create.
5696 encapType - Type of encapsulation.
5697 returns:
5698 main.TRUE on success and main.FALSE on failure
5699 """
5700 try:
5701 network = str( network )
5702 encapType = str( encapType ).upper()
5703 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5704 cmdStr = "vpls set-encap "
5705 cmdStr += network + " " + encapType
5706 output = self.sendline( cmdStr )
5707 assert output is not None, "Error in sendline"
5708 assert "Command not found:" not in output, output
5709 assert "Error executing command" not in output, output
5710 assert "already associated to network" not in output, output
5711 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005712 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005713 return main.TRUE
5714 except AssertionError:
5715 main.log.exception( "" )
5716 return main.FALSE
5717 except TypeError:
5718 main.log.exception( self.name + ": Object not as expected" )
5719 return main.FALSE
5720 except pexpect.EOF:
5721 main.log.error( self.name + ": EOF exception found" )
5722 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005723 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005724 except Exception:
5725 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005726 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005727
5728 def interfaces( self, jsonFormat=True ):
5729 """
5730 Description: Returns result of interfaces command.
5731 Optional:
5732 * jsonFormat: enable json formatting of output
5733 Returns:
5734 The output of the command or None on error.
5735 """
5736 try:
5737 cmdStr = "interfaces"
5738 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005739 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005740 cmdStr += " -j"
5741 handle = self.sendline( cmdStr )
5742 assert handle is not None, "Error in sendline"
5743 assert "Command not found:" not in handle, handle
5744 return handle
5745 except AssertionError:
5746 main.log.exception( "" )
5747 return None
5748 except TypeError:
5749 main.log.exception( self.name + ": Object not as expected" )
5750 return None
5751 except pexpect.EOF:
5752 main.log.error( self.name + ": EOF exception found" )
5753 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005754 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005755 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005756 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005757 return None
5758 except Exception:
5759 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005760 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005761
5762 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005763 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005764 Get the timestamp of searchTerm from karaf log.
5765
5766 Arguments:
5767 splitTerm_before and splitTerm_after:
5768
5769 The terms that split the string that contains the timeStamp of
5770 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5771 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5772 and the splitTerm_after is "x"
5773
5774 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005775 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005776 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005777 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005778 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005779 return main.ERROR
5780 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005781 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005782 main.log.warn( "Captured timestamp string is empty" )
5783 return main.ERROR
5784 lines = lines[ 0 ]
5785 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005786 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005787 # get the target value
5788 line = lines.split( splitTerm_before )
5789 key = line[ 1 ].split( splitTerm_after )
5790 return int( key[ 0 ] )
5791 except IndexError:
5792 main.log.warn( "Index Error!" )
5793 return main.ERROR
5794 except AssertionError:
5795 main.log.warn( "Search Term Not Found " )
5796 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005797
5798 def workQueueAdd( self, queueName, value ):
5799 """
5800 CLI command to add a string to the specified Work Queue.
5801 This function uses the distributed primitives test app, which
5802 gives some cli access to distributed primitives for testing
5803 purposes only.
5804
5805 Required arguments:
5806 queueName - The name of the queue to add to
5807 value - The value to add to the queue
5808 returns:
5809 main.TRUE on success, main.FALSE on failure and
5810 main.ERROR on error.
5811 """
5812 try:
5813 queueName = str( queueName )
5814 value = str( value )
5815 prefix = "work-queue-test"
5816 operation = "add"
5817 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5818 output = self.distPrimitivesSend( cmdStr )
5819 if "Invalid operation name" in output:
5820 main.log.warn( output )
5821 return main.ERROR
5822 elif "Done" in output:
5823 return main.TRUE
5824 except TypeError:
5825 main.log.exception( self.name + ": Object not as expected" )
5826 return main.ERROR
5827 except Exception:
5828 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005829 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005830
5831 def workQueueAddMultiple( self, queueName, value1, value2 ):
5832 """
5833 CLI command to add two strings to the specified Work Queue.
5834 This function uses the distributed primitives test app, which
5835 gives some cli access to distributed primitives for testing
5836 purposes only.
5837
5838 Required arguments:
5839 queueName - The name of the queue to add to
5840 value1 - The first value to add to the queue
5841 value2 - The second value to add to the queue
5842 returns:
5843 main.TRUE on success, main.FALSE on failure and
5844 main.ERROR on error.
5845 """
5846 try:
5847 queueName = str( queueName )
5848 value1 = str( value1 )
5849 value2 = str( value2 )
5850 prefix = "work-queue-test"
5851 operation = "addMultiple"
5852 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5853 output = self.distPrimitivesSend( cmdStr )
5854 if "Invalid operation name" in output:
5855 main.log.warn( output )
5856 return main.ERROR
5857 elif "Done" in output:
5858 return main.TRUE
5859 except TypeError:
5860 main.log.exception( self.name + ": Object not as expected" )
5861 return main.ERROR
5862 except Exception:
5863 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005864 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005865
5866 def workQueueTakeAndComplete( self, queueName, number=1 ):
5867 """
5868 CLI command to take a value from the specified Work Queue and compelte it.
5869 This function uses the distributed primitives test app, which
5870 gives some cli access to distributed primitives for testing
5871 purposes only.
5872
5873 Required arguments:
5874 queueName - The name of the queue to add to
5875 number - The number of items to take and complete
5876 returns:
5877 main.TRUE on success, main.FALSE on failure and
5878 main.ERROR on error.
5879 """
5880 try:
5881 queueName = str( queueName )
5882 number = str( int( number ) )
5883 prefix = "work-queue-test"
5884 operation = "takeAndComplete"
5885 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5886 output = self.distPrimitivesSend( cmdStr )
5887 if "Invalid operation name" in output:
5888 main.log.warn( output )
5889 return main.ERROR
5890 elif "Done" in output:
5891 return main.TRUE
5892 except TypeError:
5893 main.log.exception( self.name + ": Object not as expected" )
5894 return main.ERROR
5895 except Exception:
5896 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005897 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005898
5899 def workQueueDestroy( self, queueName ):
5900 """
5901 CLI command to destroy the specified Work Queue.
5902 This function uses the distributed primitives test app, which
5903 gives some cli access to distributed primitives for testing
5904 purposes only.
5905
5906 Required arguments:
5907 queueName - The name of the queue to add to
5908 returns:
5909 main.TRUE on success, main.FALSE on failure and
5910 main.ERROR on error.
5911 """
5912 try:
5913 queueName = str( queueName )
5914 prefix = "work-queue-test"
5915 operation = "destroy"
5916 cmdStr = " ".join( [ prefix, queueName, operation ] )
5917 output = self.distPrimitivesSend( cmdStr )
5918 if "Invalid operation name" in output:
5919 main.log.warn( output )
5920 return main.ERROR
5921 return main.TRUE
5922 except TypeError:
5923 main.log.exception( self.name + ": Object not as expected" )
5924 return main.ERROR
5925 except Exception:
5926 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005927 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005928
5929 def workQueueTotalPending( self, queueName ):
5930 """
5931 CLI command to get the Total Pending items of the specified Work Queue.
5932 This function uses the distributed primitives test app, which
5933 gives some cli access to distributed primitives for testing
5934 purposes only.
5935
5936 Required arguments:
5937 queueName - The name of the queue to add to
5938 returns:
5939 The number of Pending items in the specified work queue or
5940 None on error
5941 """
5942 try:
5943 queueName = str( queueName )
5944 prefix = "work-queue-test"
5945 operation = "totalPending"
5946 cmdStr = " ".join( [ prefix, queueName, operation ] )
5947 output = self.distPrimitivesSend( cmdStr )
5948 pattern = r'\d+'
5949 if "Invalid operation name" in output:
5950 main.log.warn( output )
5951 return None
5952 else:
5953 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005954 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005955 except ( AttributeError, TypeError ):
5956 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5957 return None
5958 except Exception:
5959 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005960 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005961
5962 def workQueueTotalCompleted( self, queueName ):
5963 """
5964 CLI command to get the Total Completed items of the specified Work Queue.
5965 This function uses the distributed primitives test app, which
5966 gives some cli access to distributed primitives for testing
5967 purposes only.
5968
5969 Required arguments:
5970 queueName - The name of the queue to add to
5971 returns:
5972 The number of complete items in the specified work queue or
5973 None on error
5974 """
5975 try:
5976 queueName = str( queueName )
5977 prefix = "work-queue-test"
5978 operation = "totalCompleted"
5979 cmdStr = " ".join( [ prefix, queueName, operation ] )
5980 output = self.distPrimitivesSend( cmdStr )
5981 pattern = r'\d+'
5982 if "Invalid operation name" in output:
5983 main.log.warn( output )
5984 return None
5985 else:
5986 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005987 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005988 except ( AttributeError, TypeError ):
5989 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5990 return None
5991 except Exception:
5992 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005993 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005994
5995 def workQueueTotalInProgress( self, queueName ):
5996 """
5997 CLI command to get the Total In Progress items of the specified Work Queue.
5998 This function uses the distributed primitives test app, which
5999 gives some cli access to distributed primitives for testing
6000 purposes only.
6001
6002 Required arguments:
6003 queueName - The name of the queue to add to
6004 returns:
6005 The number of In Progress items in the specified work queue or
6006 None on error
6007 """
6008 try:
6009 queueName = str( queueName )
6010 prefix = "work-queue-test"
6011 operation = "totalInProgress"
6012 cmdStr = " ".join( [ prefix, queueName, operation ] )
6013 output = self.distPrimitivesSend( cmdStr )
6014 pattern = r'\d+'
6015 if "Invalid operation name" in output:
6016 main.log.warn( output )
6017 return None
6018 else:
6019 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006020 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006021 except ( AttributeError, TypeError ):
6022 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6023 return None
6024 except Exception:
6025 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006026 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00006027
6028 def events( self, args='-a' ):
6029 """
6030 Description: Returns events -a command output
6031 Optional:
6032 add other arguments
6033 """
6034 try:
6035 cmdStr = "events"
6036 if args:
6037 cmdStr += " " + args
6038 handle = self.sendline( cmdStr )
6039 assert handle is not None, "Error in sendline"
6040 assert "Command not found:" not in handle, handle
6041 return handle
6042 except AssertionError:
6043 main.log.exception( "" )
6044 return None
6045 except TypeError:
6046 main.log.exception( self.name + ": Object not as expected" )
6047 return None
6048 except pexpect.EOF:
6049 main.log.error( self.name + ": EOF exception found" )
6050 main.log.error( self.name + ": " + self.handle.before )
6051 main.cleanAndExit()
6052 except Exception:
6053 main.log.exception( self.name + ": Uncaught exception!" )
6054 main.cleanAndExit()
6055
6056 def getMaster( self, deviceID ):
6057 """
6058 Description: Obtains current master using "roles" command for a specific deviceID
6059 """
6060 try:
6061 return str( self.getRole( deviceID )[ 'master' ] )
6062 except AssertionError:
6063 main.log.exception( "" )
6064 return None
6065 except TypeError:
6066 main.log.exception( self.name + ": Object not as expected" )
6067 return None
6068 except pexpect.EOF:
6069 main.log.error( self.name + ": EOF exception found" )
6070 main.log.error( self.name + ": " + self.handle.before )
6071 main.cleanAndExit()
6072 except Exception:
6073 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006074 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006075
6076 def issu( self ):
6077 """
6078 Short summary of In-Service Software Upgrade status
6079
6080 Returns the output of the cli command or None on Error
6081 """
6082 try:
6083 cmdStr = "issu"
6084 handle = self.sendline( cmdStr )
6085 assert handle is not None, "Error in sendline"
6086 assert "Command not found:" not in handle, handle
6087 assert "Unsupported command:" not in handle, handle
6088 return handle
6089 except AssertionError:
6090 main.log.exception( "" )
6091 return None
6092 except TypeError:
6093 main.log.exception( self.name + ": Object not as expected" )
6094 return None
6095 except pexpect.EOF:
6096 main.log.error( self.name + ": EOF exception found" )
6097 main.log.error( self.name + ": " + self.handle.before )
6098 main.cleanAndExit()
6099 except Exception:
6100 main.log.exception( self.name + ": Uncaught exception!" )
6101 main.cleanAndExit()
6102
6103 def issuInit( self ):
6104 """
6105 Initiates an In-Service Software Upgrade
6106
6107 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6108 """
6109 try:
6110 cmdStr = "issu init"
6111 handle = self.sendline( cmdStr )
6112 assert handle is not None, "Error in sendline"
6113 assert "Command not found:" not in handle, handle
6114 assert "Unsupported command:" not in handle, handle
6115 if "Initialized" in handle:
6116 return main.TRUE
6117 else:
6118 return main.FALSE
6119 except AssertionError:
6120 main.log.exception( "" )
6121 return main.ERROR
6122 except TypeError:
6123 main.log.exception( self.name + ": Object not as expected" )
6124 return main.ERROR
6125 except pexpect.EOF:
6126 main.log.error( self.name + ": EOF exception found" )
6127 main.log.error( self.name + ": " + self.handle.before )
6128 main.cleanAndExit()
6129 except Exception:
6130 main.log.exception( self.name + ": Uncaught exception!" )
6131 main.cleanAndExit()
6132
6133 def issuUpgrade( self ):
6134 """
6135 Transitions stores to upgraded nodes
6136
6137 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6138 """
6139 try:
6140 cmdStr = "issu upgrade"
6141 handle = self.sendline( cmdStr )
6142 assert handle is not None, "Error in sendline"
6143 assert "Command not found:" not in handle, handle
6144 assert "Unsupported command:" not in handle, handle
6145 if "Upgraded" in handle:
6146 return main.TRUE
6147 else:
6148 return main.FALSE
6149 except AssertionError:
6150 main.log.exception( "" )
6151 return main.ERROR
6152 except TypeError:
6153 main.log.exception( self.name + ": Object not as expected" )
6154 return main.ERROR
6155 except pexpect.EOF:
6156 main.log.error( self.name + ": EOF exception found" )
6157 main.log.error( self.name + ": " + self.handle.before )
6158 main.cleanAndExit()
6159 except Exception:
6160 main.log.exception( self.name + ": Uncaught exception!" )
6161 main.cleanAndExit()
6162
6163 def issuCommit( self ):
6164 """
6165 Finalizes an In-Service Software Upgrade
6166
6167 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6168 """
6169 try:
6170 cmdStr = "issu commit"
6171 handle = self.sendline( cmdStr )
6172 assert handle is not None, "Error in sendline"
6173 assert "Command not found:" not in handle, handle
6174 assert "Unsupported command:" not in handle, handle
6175 # TODO: Check the version returned by this command
6176 if "Committed version" in handle:
6177 return main.TRUE
6178 else:
6179 return main.FALSE
6180 except AssertionError:
6181 main.log.exception( "" )
6182 return main.ERROR
6183 except TypeError:
6184 main.log.exception( self.name + ": Object not as expected" )
6185 return main.ERROR
6186 except pexpect.EOF:
6187 main.log.error( self.name + ": EOF exception found" )
6188 main.log.error( self.name + ": " + self.handle.before )
6189 main.cleanAndExit()
6190 except Exception:
6191 main.log.exception( self.name + ": Uncaught exception!" )
6192 main.cleanAndExit()
6193
6194 def issuRollback( self ):
6195 """
6196 Rolls back an In-Service Software Upgrade
6197
6198 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6199 """
6200 try:
6201 cmdStr = "issu rollback"
6202 handle = self.sendline( cmdStr )
6203 assert handle is not None, "Error in sendline"
6204 assert "Command not found:" not in handle, handle
6205 assert "Unsupported command:" not in handle, handle
6206 # TODO: Check the version returned by this command
6207 if "Rolled back to version" in handle:
6208 return main.TRUE
6209 else:
6210 return main.FALSE
6211 except AssertionError:
6212 main.log.exception( "" )
6213 return main.ERROR
6214 except TypeError:
6215 main.log.exception( self.name + ": Object not as expected" )
6216 return main.ERROR
6217 except pexpect.EOF:
6218 main.log.error( self.name + ": EOF exception found" )
6219 main.log.error( self.name + ": " + self.handle.before )
6220 main.cleanAndExit()
6221 except Exception:
6222 main.log.exception( self.name + ": Uncaught exception!" )
6223 main.cleanAndExit()
6224
6225 def issuReset( self ):
6226 """
6227 Resets the In-Service Software Upgrade status after a rollback
6228
6229 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6230 """
6231 try:
6232 cmdStr = "issu reset"
6233 handle = self.sendline( cmdStr )
6234 assert handle is not None, "Error in sendline"
6235 assert "Command not found:" not in handle, handle
6236 assert "Unsupported command:" not in handle, handle
6237 # TODO: Check the version returned by this command
6238 if "Reset version" in handle:
6239 return main.TRUE
6240 else:
6241 return main.FALSE
6242 except AssertionError:
6243 main.log.exception( "" )
6244 return main.ERROR
6245 except TypeError:
6246 main.log.exception( self.name + ": Object not as expected" )
6247 return main.ERROR
6248 except pexpect.EOF:
6249 main.log.error( self.name + ": EOF exception found" )
6250 main.log.error( self.name + ": " + self.handle.before )
6251 main.cleanAndExit()
6252 except Exception:
6253 main.log.exception( self.name + ": Uncaught exception!" )
6254 main.cleanAndExit()
6255
6256 def issuStatus( self ):
6257 """
6258 Status of an In-Service Software Upgrade
6259
6260 Returns the output of the cli command or None on Error
6261 """
6262 try:
6263 cmdStr = "issu status"
6264 handle = self.sendline( cmdStr )
6265 assert handle is not None, "Error in sendline"
6266 assert "Command not found:" not in handle, handle
6267 assert "Unsupported command:" not in handle, handle
6268 return handle
6269 except AssertionError:
6270 main.log.exception( "" )
6271 return None
6272 except TypeError:
6273 main.log.exception( self.name + ": Object not as expected" )
6274 return None
6275 except pexpect.EOF:
6276 main.log.error( self.name + ": EOF exception found" )
6277 main.log.error( self.name + ": " + self.handle.before )
6278 main.cleanAndExit()
6279 except Exception:
6280 main.log.exception( self.name + ": Uncaught exception!" )
6281 main.cleanAndExit()
6282
6283 def issuVersion( self ):
6284 """
6285 Get the version of an In-Service Software Upgrade
6286
6287 Returns the output of the cli command or None on Error
6288 """
6289 try:
6290 cmdStr = "issu version"
6291 handle = self.sendline( cmdStr )
6292 assert handle is not None, "Error in sendline"
6293 assert "Command not found:" not in handle, handle
6294 assert "Unsupported command:" not in handle, handle
6295 return handle
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()
You Wange24d6272018-03-27 21:18:50 -07006309
6310 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6311 """
6312 Create a multicast route by calling 'mcast-join' command
6313 sIP: source IP of the multicast route
6314 groupIP: group IP of the multicast route
6315 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6316 dPorts: a list of destination ports of the multicast route
6317 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6318 """
6319 try:
6320 cmdStr = "mcast-join"
6321 cmdStr += " " + str( sIP )
6322 cmdStr += " " + str( groupIP )
6323 cmdStr += " " + str( sPort )
6324 assert isinstance( dPorts, list )
6325 for dPort in dPorts:
6326 cmdStr += " " + str( dPort )
6327 handle = self.sendline( cmdStr )
6328 assert handle is not None, "Error in sendline"
6329 assert "Command not found:" not in handle, handle
6330 assert "Unsupported command:" not in handle, handle
6331 assert "Error executing command" not in handle, handle
6332 if "Added the mcast route" in handle:
6333 return main.TRUE
6334 else:
6335 return main.FALSE
6336 except AssertionError:
6337 main.log.exception( "" )
6338 return None
6339 except TypeError:
6340 main.log.exception( self.name + ": Object not as expected" )
6341 return None
6342 except pexpect.EOF:
6343 main.log.error( self.name + ": EOF exception found" )
6344 main.log.error( self.name + ": " + self.handle.before )
6345 main.cleanAndExit()
6346 except Exception:
6347 main.log.exception( self.name + ": Uncaught exception!" )
6348 main.cleanAndExit()
6349
6350 def mcastDelete( self, sIP, groupIP, dPorts ):
6351 """
6352 Delete a multicast route by calling 'mcast-delete' command
6353 sIP: source IP of the multicast route
6354 groupIP: group IP of the multicast route
6355 dPorts: a list of destination ports of the multicast route
6356 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6357 """
6358 try:
6359 cmdStr = "mcast-delete"
6360 cmdStr += " " + str( sIP )
6361 cmdStr += " " + str( groupIP )
6362 assert isinstance( dPorts, list )
6363 for dPort in dPorts:
6364 cmdStr += " " + str( dPort )
6365 handle = self.sendline( cmdStr )
6366 assert handle is not None, "Error in sendline"
6367 assert "Command not found:" not in handle, handle
6368 assert "Unsupported command:" not in handle, handle
6369 assert "Error executing command" not in handle, handle
6370 if "Updated the mcast route" in handle:
6371 return main.TRUE
6372 else:
6373 return main.FALSE
6374 except AssertionError:
6375 main.log.exception( "" )
6376 return None
6377 except TypeError:
6378 main.log.exception( self.name + ": Object not as expected" )
6379 return None
6380 except pexpect.EOF:
6381 main.log.error( self.name + ": EOF exception found" )
6382 main.log.error( self.name + ": " + self.handle.before )
6383 main.cleanAndExit()
6384 except Exception:
6385 main.log.exception( self.name + ": Uncaught exception!" )
6386 main.cleanAndExit()
6387
6388 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6389 """
6390 Create a multicast route by calling 'mcast-host-join' command
6391 sAddr: we can provide * for ASM or a specific address for SSM
6392 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006393 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006394 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6395 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6396 """
6397 try:
6398 cmdStr = "mcast-host-join"
6399 cmdStr += " -sAddr " + str( sAddr )
6400 cmdStr += " -gAddr " + str( gAddr )
6401 assert isinstance( srcs, list )
6402 for src in srcs:
6403 cmdStr += " -srcs " + str( src )
6404 assert isinstance( sinks, list )
6405 for sink in sinks:
6406 cmdStr += " -sinks " + str( sink )
6407 handle = self.sendline( cmdStr )
6408 assert handle is not None, "Error in sendline"
6409 assert "Command not found:" not in handle, handle
6410 assert "Unsupported command:" not in handle, handle
6411 assert "Error executing command" not in handle, handle
6412 if "Added 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
6430 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6431 """
6432 Delete multicast sink(s) by calling 'mcast-host-delete' command
6433 sAddr: we can provide * for ASM or a specific address for SSM
6434 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006435 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006436 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-host-delete"
6441 cmdStr += " -sAddr " + str( sAddr )
6442 cmdStr += " -gAddr " + str( gAddr )
6443 if host:
6444 cmdStr += " -h " + str( host )
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 Wang547893e2018-05-08 13:34:59 -07006470 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6471 """
6472 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6473 sAddr: we can provide * for ASM or a specific address for SSM
6474 gAddr: specifies multicast group address
6475 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6476 will delete the route if not specified
6477 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6478 """
6479 try:
6480 cmdStr = "mcast-sink-delete"
6481 cmdStr += " -sAddr " + str( sAddr )
6482 cmdStr += " -gAddr " + str( gAddr )
6483 if sink:
6484 cmdStr += " -s " + str( sink )
6485 handle = self.sendline( cmdStr )
6486 assert handle is not None, "Error in sendline"
6487 assert "Command not found:" not in handle, handle
6488 assert "Unsupported command:" not in handle, handle
6489 assert "Error executing command" not in handle, handle
6490 if "Updated the mcast route" in handle:
6491 return main.TRUE
6492 elif "Deleted the mcast route" in handle:
6493 return main.TRUE
6494 else:
6495 return main.FALSE
6496 except AssertionError:
6497 main.log.exception( "" )
6498 return None
6499 except TypeError:
6500 main.log.exception( self.name + ": Object not as expected" )
6501 return None
6502 except pexpect.EOF:
6503 main.log.error( self.name + ": EOF exception found" )
6504 main.log.error( self.name + ": " + self.handle.before )
6505 main.cleanAndExit()
6506 except Exception:
6507 main.log.exception( self.name + ": Uncaught exception!" )
6508 main.cleanAndExit()
6509
You Wange24d6272018-03-27 21:18:50 -07006510 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6511 """
6512 Delete multicast src(s) by calling 'mcast-source-delete' command
6513 sAddr: we can provide * for ASM or a specific address for SSM
6514 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006515 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 -07006516 will delete the route if not specified
6517 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6518 """
6519 try:
6520 cmdStr = "mcast-source-delete"
6521 cmdStr += " -sAddr " + str( sAddr )
6522 cmdStr += " -gAddr " + str( gAddr )
6523 if srcs:
6524 assert isinstance( srcs, list )
6525 for src in srcs:
6526 cmdStr += " -src " + str( src )
6527 handle = self.sendline( cmdStr )
6528 assert handle is not None, "Error in sendline"
6529 assert "Command not found:" not in handle, handle
6530 assert "Unsupported command:" not in handle, handle
6531 assert "Error executing command" not in handle, handle
6532 if "Updated the mcast route" in handle:
6533 return main.TRUE
6534 elif "Deleted the mcast route" in handle:
6535 return main.TRUE
6536 else:
6537 return main.FALSE
6538 except AssertionError:
6539 main.log.exception( "" )
6540 return None
6541 except TypeError:
6542 main.log.exception( self.name + ": Object not as expected" )
6543 return None
6544 except pexpect.EOF:
6545 main.log.error( self.name + ": EOF exception found" )
6546 main.log.error( self.name + ": " + self.handle.before )
6547 main.cleanAndExit()
6548 except Exception:
6549 main.log.exception( self.name + ": Uncaught exception!" )
6550 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006551
6552 def netcfg( self, jsonFormat=True, args="" ):
6553 """
6554 Run netcfg cli command with given args
6555 """
6556 try:
6557 cmdStr = "netcfg"
6558 if jsonFormat:
6559 cmdStr = cmdStr + " -j"
6560 if args:
6561 cmdStr = cmdStr + " " + str( args )
6562 handle = self.sendline( cmdStr )
6563 assert handle is not None, "Error in sendline"
6564 assert "Command not found:" not in handle, handle
6565 assert "Unsupported command:" not in handle, handle
6566 assert "Error executing command" not in handle, handle
6567 return handle
6568 except AssertionError:
6569 main.log.exception( "" )
6570 return None
6571 except TypeError:
6572 main.log.exception( self.name + ": Object not as expected" )
6573 return None
6574 except pexpect.EOF:
6575 main.log.error( self.name + ": EOF exception found" )
6576 main.log.error( self.name + ": " + self.handle.before )
6577 main.cleanAndExit()
6578 except Exception:
6579 main.log.exception( self.name + ": Uncaught exception!" )
6580 main.cleanAndExit()
6581
You Wang0fa76e72018-05-18 11:33:25 -07006582 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006583 """
You Wang54b1d672018-06-11 16:44:13 -07006584 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006585 Options:
6586 sAddr: IP address of the source host
6587 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006588 ipv6: True if hosts are IPv6
6589 verbose: return verbose t3 output if True
6590 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006591 """
6592 try:
6593 # Collect information of both hosts from onos
6594 hosts = self.hosts()
6595 hosts = json.loads( hosts )
6596 sHost = None
6597 dHost = None
6598 for host in hosts:
6599 if sAddr in host[ "ipAddresses" ]:
6600 sHost = host
6601 elif dAddr in host[ "ipAddresses" ]:
6602 dHost = host
6603 if sHost and dHost:
6604 break
6605 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006606 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006607 if simple:
6608 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006609 cmdStr = "t3-troubleshoot-simple"
6610 if verbose:
6611 cmdStr += " -vv"
6612 if ipv6:
6613 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006614 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006615 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006616 else:
You Wang54b1d672018-06-11 16:44:13 -07006617 for location in sHost[ "locations" ]:
6618 cmdStr = "t3-troubleshoot"
6619 if verbose:
6620 cmdStr += " -vv"
6621 if ipv6:
6622 cmdStr += " -et ipv6"
6623 cmdStr += " -s " + str( sAddr )
6624 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6625 cmdStr += " -sm " + str( sHost[ "mac" ] )
6626 if sHost[ "vlan" ] != "None":
6627 cmdStr += " -vid " + sHost[ "vlan" ]
6628 cmdStr += " -d " + str( dAddr )
6629 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6630 netcfg = json.loads( netcfg )
6631 assert netcfg, "Failed to get netcfg"
6632 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6633 cmdList.append( cmdStr )
6634 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006635 except AssertionError:
6636 main.log.exception( "" )
6637 return None
6638 except ( KeyError, TypeError ):
6639 main.log.exception( self.name + ": Object not as expected" )
6640 return None
6641 except Exception:
6642 main.log.exception( self.name + ": Uncaught exception!" )
6643 main.cleanAndExit()
6644
6645 def t3( self, sAddr, dAddr, ipv6=False ):
6646 """
You Wang54b1d672018-06-11 16:44:13 -07006647 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006648 Options:
6649 sAddr: IP address of the source host
6650 dAddr: IP address of the destination host
6651 """
6652 try:
You Wang54b1d672018-06-11 16:44:13 -07006653 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6654 assert cmdList is not None, "composeT3Command returned None"
6655 t3Output = ""
6656 for cmdStr in cmdList:
6657 handle = self.sendline( cmdStr )
6658 assert handle is not None, "Error in sendline"
6659 assert "Command not found:" not in handle, handle
6660 assert "Unsupported command:" not in handle, handle
6661 assert "Error executing command" not in handle, handle
6662 assert "Tracing packet" in handle
6663 t3Output += handle
6664 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006665 except AssertionError:
6666 main.log.exception( "" )
6667 return None
6668 except pexpect.EOF:
6669 main.log.error( self.name + ": EOF exception found" )
6670 main.log.error( self.name + ": " + self.handle.before )
6671 main.cleanAndExit()
6672 except Exception:
6673 main.log.exception( self.name + ": Uncaught exception!" )
6674 main.cleanAndExit()