blob: a6fd4e9aa7d5b9d7d4fdf87549f03b1b82dbeb00 [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:
599 output = response.split( cmdStr.strip(), 1 )
Jon Hall0623dd42018-11-13 14:32:23 -0800600 if len(output) < 2:
601 output = response.split( endStr.strip()[-5:], 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700602 if output:
603 if debug:
604 main.log.debug( self.name + ": split output" )
605 for r in output:
606 main.log.debug( self.name + ": " + repr( r ) )
607 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800608 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800609 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700610 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800611 return output
GlennRCed771242016-01-13 17:02:47 -0800612 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700613 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800614 if debug:
615 main.log.debug( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700616 self.handle.send( "\x03" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800617 self.handle.expect( self.karafPrompt )
GlennRCed771242016-01-13 17:02:47 -0800618 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700619 except IndexError:
620 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700621 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700622 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800623 except TypeError:
624 main.log.exception( self.name + ": Object not as expected" )
625 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400626 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800627 main.log.error( self.name + ": EOF exception found" )
628 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700629 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700630 return None
631 else:
Devin Lim44075962017-08-11 10:56:37 -0700632 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800633 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800634 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700635 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700636 return None
637 else:
Devin Lim44075962017-08-11 10:56:37 -0700638 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400639
Jon Halld5a94fb2018-11-13 14:32:23 -0800640 def lineCount( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True ):
641 """
642 A wrapper around sendline(). Will return the number of lines returned or None on error
643
644 Required Arguments:
645 cmdStr - String to send to the pexpect session
646
647 Optional Arguments:
648 showResponse - Defaults to False. If True will log the response.
649 debug - Defaults to False. If True, will enable debug logging.
650 timeout - Defaults to 10. Amount of time in seconds for a command to return
651 before a timeout.
652 noExit - Defaults to False. If True, will not exit TestON in the event of a
653 closed channel, but instead return None
654 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.
655
656 Warning: There are no sanity checking to commands sent using this method.
657
658 """
659 try:
660 numLines = self.sendline( cmdStr, showResponse, debug, timeout, noExit, relaxedRegex )
661 parsed = numLines.split( " " )
662 if len( parsed ) != 2:
663 main.log.warn( "Warning, output of karaf's wc may have changed" )
664 return parsed[0]
665 except IndexError:
666 main.log.exception( self.name + ": Object not as expected" )
667 main.log.debug( "response: {}".format( repr( response ) ) )
668 return None
669 except TypeError:
670 main.log.exception( self.name + ": Object not as expected" )
671 return None
672 except Exception:
673 main.log.exception( self.name + ": Uncaught exception!" )
674 if noExit:
675 return None
676 else:
677 main.cleanAndExit()
678
kelvin8ec71442015-01-15 16:57:00 -0800679 # IMPORTANT NOTE:
680 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800681 # the cli command changing 'a:b' with 'aB'.
682 # Ex ) onos:topology > onosTopology
683 # onos:links > onosLinks
684 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800685
kelvin-onlabd3b64892015-01-20 13:26:24 -0800686 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800687 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400688 Adds a new cluster node by ID and address information.
689 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800690 * nodeId
691 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400692 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800693 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800694 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400695 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800696 cmdStr = "add-node " + str( nodeId ) + " " +\
697 str( ONOSIp ) + " " + str( tcpPort )
698 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700699 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800700 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800701 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700702 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800703 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800704 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400705 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800706 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400707 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800708 except AssertionError:
709 main.log.exception( "" )
710 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800711 except TypeError:
712 main.log.exception( self.name + ": Object not as expected" )
713 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400714 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800715 main.log.error( self.name + ": EOF exception found" )
716 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700717 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800718 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800719 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700720 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400721
kelvin-onlabd3b64892015-01-20 13:26:24 -0800722 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800723 """
andrewonlab86dc3082014-10-13 18:18:38 -0400724 Removes a cluster by ID
725 Issues command: 'remove-node [<node-id>]'
726 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800727 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800728 """
andrewonlab86dc3082014-10-13 18:18:38 -0400729 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400730
kelvin-onlabd3b64892015-01-20 13:26:24 -0800731 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700732 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700733 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800734 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700735 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700736 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700737 main.log.error( handle )
738 return main.FALSE
739 else:
740 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800741 except AssertionError:
742 main.log.exception( "" )
743 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800744 except TypeError:
745 main.log.exception( self.name + ": Object not as expected" )
746 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400747 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800748 main.log.error( self.name + ": EOF exception found" )
749 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700750 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800751 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800752 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700753 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400754
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700755 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800756 """
andrewonlab7c211572014-10-15 16:45:20 -0400757 List the nodes currently visible
758 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700759 Optional argument:
760 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800761 """
andrewonlab7c211572014-10-15 16:45:20 -0400762 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700763 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700764 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700765 cmdStr += " -j"
766 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700767 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800768 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700769 return output
Jon Hallc6793552016-01-19 14:18:37 -0800770 except AssertionError:
771 main.log.exception( "" )
772 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800773 except TypeError:
774 main.log.exception( self.name + ": Object not as expected" )
775 return None
andrewonlab7c211572014-10-15 16:45:20 -0400776 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800777 main.log.error( self.name + ": EOF exception found" )
778 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700779 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800780 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800781 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700782 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400783
kelvin8ec71442015-01-15 16:57:00 -0800784 def topology( self ):
785 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700786 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700787 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700788 Return:
789 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800790 """
andrewonlab95ce8322014-10-13 14:12:04 -0400791 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700792 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800793 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800794 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800795 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700796 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400797 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800798 except AssertionError:
799 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800800 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800801 except TypeError:
802 main.log.exception( self.name + ": Object not as expected" )
803 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400804 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800805 main.log.error( self.name + ": EOF exception found" )
806 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700807 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800808 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800809 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700810 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800811
jenkins7ead5a82015-03-13 10:28:21 -0700812 def deviceRemove( self, deviceId ):
813 """
814 Removes particular device from storage
815
816 TODO: refactor this function
817 """
818 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700819 cmdStr = "device-remove " + str( deviceId )
820 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800821 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800822 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700823 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700824 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700825 main.log.error( handle )
826 return main.FALSE
827 else:
828 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800829 except AssertionError:
830 main.log.exception( "" )
831 return None
jenkins7ead5a82015-03-13 10:28:21 -0700832 except TypeError:
833 main.log.exception( self.name + ": Object not as expected" )
834 return None
835 except pexpect.EOF:
836 main.log.error( self.name + ": EOF exception found" )
837 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700838 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700839 except Exception:
840 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700841 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700842
You Wang3b9689a2018-08-30 12:24:00 -0700843 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800844 """
Jon Hall7b02d952014-10-17 20:14:54 -0400845 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400846 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800847 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800848 """
andrewonlab86dc3082014-10-13 18:18:38 -0400849 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700850 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800851 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700852 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700853 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800854 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800855 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700856 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800857 except AssertionError:
858 main.log.exception( "" )
859 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800860 except TypeError:
861 main.log.exception( self.name + ": Object not as expected" )
862 return None
andrewonlab7c211572014-10-15 16:45:20 -0400863 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800864 main.log.error( self.name + ": EOF exception found" )
865 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700866 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800867 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800868 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700869 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400870
kelvin-onlabd3b64892015-01-20 13:26:24 -0800871 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800872 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800873 This balances the devices across all controllers
874 by issuing command: 'onos> onos:balance-masters'
875 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800876 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800877 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800878 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700879 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800880 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800881 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700882 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700883 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700884 main.log.error( handle )
885 return main.FALSE
886 else:
887 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800888 except AssertionError:
889 main.log.exception( "" )
890 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800891 except TypeError:
892 main.log.exception( self.name + ": Object not as expected" )
893 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800894 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800895 main.log.error( self.name + ": EOF exception found" )
896 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700897 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800898 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800899 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700900 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800901
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000902 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700903 """
904 Returns the output of the masters command.
905 Optional argument:
906 * jsonFormat - boolean indicating if you want output in json
907 """
908 try:
909 cmdStr = "onos:masters"
910 if jsonFormat:
911 cmdStr += " -j"
912 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700913 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800914 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700915 return output
Jon Hallc6793552016-01-19 14:18:37 -0800916 except AssertionError:
917 main.log.exception( "" )
918 return None
acsmars24950022015-07-30 18:00:43 -0700919 except TypeError:
920 main.log.exception( self.name + ": Object not as expected" )
921 return None
922 except pexpect.EOF:
923 main.log.error( self.name + ": EOF exception found" )
924 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700925 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700926 except Exception:
927 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700928 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700929
Jon Hallc6793552016-01-19 14:18:37 -0800930 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700931 """
932 Uses the master command to check that the devices' leadership
933 is evenly divided
934
935 Dependencies: checkMasters() and summary()
936
Jon Hall6509dbf2016-06-21 17:01:17 -0700937 Returns main.TRUE if the devices are balanced
938 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700939 Exits on Exception
940 Returns None on TypeError
941 """
942 try:
Jon Hallc6793552016-01-19 14:18:37 -0800943 summaryOutput = self.summary()
944 totalDevices = json.loads( summaryOutput )[ "devices" ]
945 except ( TypeError, ValueError ):
946 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
947 return None
948 try:
acsmars24950022015-07-30 18:00:43 -0700949 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800950 mastersOutput = self.checkMasters()
951 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700952 first = masters[ 0 ][ "size" ]
953 for master in masters:
954 totalOwnedDevices += master[ "size" ]
955 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
956 main.log.error( "Mastership not balanced" )
957 main.log.info( "\n" + self.checkMasters( False ) )
958 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700959 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700960 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700961 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800962 except ( TypeError, ValueError ):
963 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700964 return None
965 except pexpect.EOF:
966 main.log.error( self.name + ": EOF exception found" )
967 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700968 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700969 except Exception:
970 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700971 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700972
YPZhangfebf7302016-05-24 16:45:56 -0700973 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800974 """
Jon Halle8217482014-10-17 13:49:14 -0400975 Lists all core links
976 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800977 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800978 """
Jon Halle8217482014-10-17 13:49:14 -0400979 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700980 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800981 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700982 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700983 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800984 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800985 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700986 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800987 except AssertionError:
988 main.log.exception( "" )
989 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800990 except TypeError:
991 main.log.exception( self.name + ": Object not as expected" )
992 return None
Jon Halle8217482014-10-17 13:49:14 -0400993 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800994 main.log.error( self.name + ": EOF exception found" )
995 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700996 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800997 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800998 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700999 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001000
You Wang3b9689a2018-08-30 12:24:00 -07001001 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001002 """
Jon Halle8217482014-10-17 13:49:14 -04001003 Lists all ports
1004 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001005 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001006 """
Jon Halle8217482014-10-17 13:49:14 -04001007 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001008 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001009 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001010 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -07001011 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001012 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001013 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001014 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001015 except AssertionError:
1016 main.log.exception( "" )
1017 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001018 except TypeError:
1019 main.log.exception( self.name + ": Object not as expected" )
1020 return None
Jon Halle8217482014-10-17 13:49:14 -04001021 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001022 main.log.error( self.name + ": EOF exception found" )
1023 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001024 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001025 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001026 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001027 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001028
kelvin-onlabd3b64892015-01-20 13:26:24 -08001029 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001030 """
Jon Hall983a1702014-10-28 18:44:22 -04001031 Lists all devices and the controllers with roles assigned to them
1032 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001033 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001034 """
andrewonlab7c211572014-10-15 16:45:20 -04001035 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001036 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001037 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001038 cmdStr += " -j"
1039 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001040 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001041 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001042 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001043 except AssertionError:
1044 main.log.exception( "" )
1045 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001046 except TypeError:
1047 main.log.exception( self.name + ": Object not as expected" )
1048 return None
Jon Hall983a1702014-10-28 18:44:22 -04001049 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001050 main.log.error( self.name + ": EOF exception found" )
1051 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001052 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001053 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001054 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001055 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -04001056
kelvin-onlabd3b64892015-01-20 13:26:24 -08001057 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001058 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001059 Given the a string containing the json representation of the "roles"
1060 cli command and a partial or whole device id, returns a json object
1061 containing the roles output for the first device whose id contains
1062 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001063
1064 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001065 A dict of the role assignments for the given device or
1066 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001067 """
Jon Hall983a1702014-10-28 18:44:22 -04001068 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001069 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001070 return None
1071 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001072 rawRoles = self.roles()
1073 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001074 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001075 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001076 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001077 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001078 return device
1079 return None
Jon Hallc6793552016-01-19 14:18:37 -08001080 except ( TypeError, ValueError ):
1081 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001082 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001083 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001084 main.log.error( self.name + ": EOF exception found" )
1085 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001086 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001087 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001088 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001089 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001090
kelvin-onlabd3b64892015-01-20 13:26:24 -08001091 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001092 """
Jon Hall94fd0472014-12-08 11:52:42 -08001093 Iterates through each device and checks if there is a master assigned
1094 Returns: main.TRUE if each device has a master
1095 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001096 """
Jon Hall94fd0472014-12-08 11:52:42 -08001097 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001098 rawRoles = self.roles()
1099 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001100 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001101 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001102 # print device
1103 if device[ 'master' ] == "none":
1104 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001105 return main.FALSE
1106 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001107 except ( TypeError, ValueError ):
1108 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001109 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001110 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001111 main.log.error( self.name + ": EOF exception found" )
1112 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001113 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001114 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001115 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001116 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001117
kelvin-onlabd3b64892015-01-20 13:26:24 -08001118 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001119 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001120 Returns string of paths, and the cost.
1121 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001122 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001123 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001124 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1125 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001126 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001127 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001128 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001129 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001130 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001131 else:
kelvin8ec71442015-01-15 16:57:00 -08001132 path = handle.split( ";" )[ 0 ]
1133 cost = handle.split( ";" )[ 1 ]
1134 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001135 except AssertionError:
1136 main.log.exception( "" )
1137 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001138 except TypeError:
1139 main.log.exception( self.name + ": Object not as expected" )
1140 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001141 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001142 main.log.error( self.name + ": EOF exception found" )
1143 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001144 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001145 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001146 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001147 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001148
kelvin-onlabd3b64892015-01-20 13:26:24 -08001149 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001150 """
Jon Hallffb386d2014-11-21 13:43:38 -08001151 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001152 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001153 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001154 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001155 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001156 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001157 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001158 cmdStr += " -j"
1159 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001160 if handle:
1161 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001162 # TODO: Maybe make this less hardcoded
1163 # ConsistentMap Exceptions
1164 assert "org.onosproject.store.service" not in handle
1165 # Node not leader
1166 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001167 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001168 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001169 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001170 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001171 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001172 except TypeError:
1173 main.log.exception( self.name + ": Object not as expected" )
1174 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001175 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001176 main.log.error( self.name + ": EOF exception found" )
1177 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001178 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001179 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001180 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001181 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001182
kelvin-onlabd3b64892015-01-20 13:26:24 -08001183 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001184 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001185 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001186
Jon Hallefbd9792015-03-05 16:11:36 -08001187 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001188 partial mac address
1189
Jon Hall42db6dc2014-10-24 19:03:48 -04001190 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001191 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001192 try:
kelvin8ec71442015-01-15 16:57:00 -08001193 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001194 return None
1195 else:
1196 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001197 rawHosts = self.hosts()
1198 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001199 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001200 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001201 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001202 if not host:
1203 pass
1204 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001205 return host
1206 return None
Jon Hallc6793552016-01-19 14:18:37 -08001207 except ( TypeError, ValueError ):
1208 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001209 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001210 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001211 main.log.error( self.name + ": EOF exception found" )
1212 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001213 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001214 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001215 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001216 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001217
kelvin-onlabd3b64892015-01-20 13:26:24 -08001218 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001219 """
1220 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001221 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001222
andrewonlab3f0a4af2014-10-17 12:25:14 -04001223 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001224 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001225 IMPORTANT:
1226 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001227 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001228 Furthermore, it assumes that value of VLAN is '-1'
1229 Description:
kelvin8ec71442015-01-15 16:57:00 -08001230 Converts mininet hosts ( h1, h2, h3... ) into
1231 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1232 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001233 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001234 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001235
kelvin-onlabd3b64892015-01-20 13:26:24 -08001236 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001237 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001238 hostHex = hex( int( host ) ).zfill( 12 )
1239 hostHex = str( hostHex ).replace( 'x', '0' )
1240 i = iter( str( hostHex ) )
1241 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1242 hostHex = hostHex + "/-1"
1243 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001244
kelvin-onlabd3b64892015-01-20 13:26:24 -08001245 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001246
Jon Halld4d4b372015-01-28 16:02:41 -08001247 except TypeError:
1248 main.log.exception( self.name + ": Object not as expected" )
1249 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001250 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001251 main.log.error( self.name + ": EOF exception found" )
1252 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001253 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001254 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001255 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001256 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001257
You Wangbc898b82018-05-03 16:22:34 -07001258 def verifyHostLocation( self, hostIp, location ):
1259 """
1260 Description:
1261 Verify the host given is discovered in all locations expected
1262 Required:
1263 hostIp: IP address of the host
1264 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1265 Could be a string or list
1266 Returns:
1267 main.TRUE if host is discovered on all locations provided
1268 main.FALSE otherwise
1269 """
1270 import json
1271 locations = [ location ] if isinstance( location, str ) else location
1272 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1273 try:
1274 hosts = self.hosts()
1275 hosts = json.loads( hosts )
1276 targetHost = None
1277 for host in hosts:
1278 if hostIp in host[ "ipAddresses" ]:
1279 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001280 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001281 result = main.TRUE
1282 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1283 for loc in locations:
1284 discovered = False
1285 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001286 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1287 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001288 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001289 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001290 break
1291 if discovered:
1292 locationsDiscovered.remove( locDiscovered )
1293 else:
1294 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1295 result = main.FALSE
1296 if locationsDiscovered:
1297 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1298 result = main.FALSE
1299 return result
1300 except KeyError:
1301 main.log.exception( self.name + ": host data not as expected: " + hosts )
1302 return None
1303 except pexpect.EOF:
1304 main.log.error( self.name + ": EOF exception found" )
1305 main.log.error( self.name + ": " + self.handle.before )
1306 main.cleanAndExit()
1307 except Exception:
1308 main.log.exception( self.name + ": Uncaught exception" )
1309 return None
1310
You Wang53dba1e2018-02-02 17:45:44 -08001311 def verifyHostIp( self, hostList=[], prefix="" ):
1312 """
1313 Description:
1314 Verify that all hosts have IP address assigned to them
1315 Optional:
1316 hostList: If specified, verifications only happen to the hosts
1317 in hostList
1318 prefix: at least one of the ip address assigned to the host
1319 needs to have the specified prefix
1320 Returns:
1321 main.TRUE if all hosts have specific IP address assigned;
1322 main.FALSE otherwise
1323 """
1324 import json
1325 try:
1326 hosts = self.hosts()
1327 hosts = json.loads( hosts )
1328 if not hostList:
1329 hostList = [ host[ "id" ] for host in hosts ]
1330 for host in hosts:
1331 hostId = host[ "id" ]
1332 if hostId not in hostList:
1333 continue
1334 ipList = host[ "ipAddresses" ]
1335 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1336 if not ipList:
1337 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1338 else:
1339 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1340 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1341 else:
1342 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1343 hostList.remove( hostId )
1344 if hostList:
1345 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1346 return main.FALSE
1347 else:
1348 return main.TRUE
1349 except KeyError:
1350 main.log.exception( self.name + ": host data not as expected: " + hosts )
1351 return None
1352 except pexpect.EOF:
1353 main.log.error( self.name + ": EOF exception found" )
1354 main.log.error( self.name + ": " + self.handle.before )
1355 main.cleanAndExit()
1356 except Exception:
1357 main.log.exception( self.name + ": Uncaught exception" )
1358 return None
1359
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001360 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001361 """
andrewonlabe6745342014-10-17 14:29:13 -04001362 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001363 * hostIdOne: ONOS host id for host1
1364 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001365 Optional:
1366 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001367 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001368 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001369 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001370 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001371 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001372 Returns:
1373 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001374 """
andrewonlabe6745342014-10-17 14:29:13 -04001375 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001376 cmdStr = "add-host-intent "
1377 if vlanId:
1378 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001379 if setVlan:
1380 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001381 if encap:
1382 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001383 if bandwidth:
1384 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001385 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001386 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001387 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001388 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001389 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001390 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001391 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001392 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001393 else:
1394 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001395 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001396 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001397 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001398 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001399 else:
1400 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001401 main.log.debug( "Response from ONOS was: " +
1402 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001403 return None
Jon Hallc6793552016-01-19 14:18:37 -08001404 except AssertionError:
1405 main.log.exception( "" )
1406 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001407 except TypeError:
1408 main.log.exception( self.name + ": Object not as expected" )
1409 return None
andrewonlabe6745342014-10-17 14:29:13 -04001410 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001411 main.log.error( self.name + ": EOF exception found" )
1412 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001413 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001414 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001415 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001416 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001417
kelvin-onlabd3b64892015-01-20 13:26:24 -08001418 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001419 """
andrewonlab7b31d232014-10-24 13:31:47 -04001420 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001421 * ingressDevice: device id of ingress device
1422 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001423 Optional:
1424 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001425 Description:
1426 Adds an optical intent by specifying an ingress and egress device
1427 Returns:
1428 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001429 """
andrewonlab7b31d232014-10-24 13:31:47 -04001430 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001431 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1432 " " + str( egressDevice )
1433 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001434 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001435 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001436 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001437 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001438 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001439 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001440 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001441 main.log.info( "Optical intent installed between " +
1442 str( ingressDevice ) + " and " +
1443 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001444 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001445 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001446 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001447 else:
1448 main.log.error( "Error, intent ID not found" )
1449 return None
Jon Hallc6793552016-01-19 14:18:37 -08001450 except AssertionError:
1451 main.log.exception( "" )
1452 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001453 except TypeError:
1454 main.log.exception( self.name + ": Object not as expected" )
1455 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001456 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001457 main.log.error( self.name + ": EOF exception found" )
1458 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001459 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001460 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001461 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001462 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001463
kelvin-onlabd3b64892015-01-20 13:26:24 -08001464 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001465 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001466 ingressDevice,
1467 egressDevice,
1468 portIngress="",
1469 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001470 ethType="",
1471 ethSrc="",
1472 ethDst="",
1473 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001474 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001475 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001476 ipProto="",
1477 ipSrc="",
1478 ipDst="",
1479 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001480 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001481 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001482 setVlan="",
1483 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001484 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001485 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001486 * ingressDevice: device id of ingress device
1487 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001488 Optional:
1489 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001490 * ethSrc: specify ethSrc ( i.e. src mac addr )
1491 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001492 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001493 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001494 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001495 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001496 * ipSrc: specify ip source address
1497 * ipDst: specify ip destination address
1498 * tcpSrc: specify tcp source port
1499 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001500 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001501 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001502 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001503 Description:
kelvin8ec71442015-01-15 16:57:00 -08001504 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001505 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001506 Returns:
1507 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001508
Jon Halle3f39ff2015-01-13 11:50:53 -08001509 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001510 options developers provide for point-to-point
1511 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001512 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001513 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001514 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001515
Jeremy Songsterff553672016-05-12 17:06:23 -07001516 if ethType:
1517 cmd += " --ethType " + str( ethType )
1518 if ethSrc:
1519 cmd += " --ethSrc " + str( ethSrc )
1520 if ethDst:
1521 cmd += " --ethDst " + str( ethDst )
1522 if bandwidth:
1523 cmd += " --bandwidth " + str( bandwidth )
1524 if lambdaAlloc:
1525 cmd += " --lambda "
1526 if ipProto:
1527 cmd += " --ipProto " + str( ipProto )
1528 if ipSrc:
1529 cmd += " --ipSrc " + str( ipSrc )
1530 if ipDst:
1531 cmd += " --ipDst " + str( ipDst )
1532 if tcpSrc:
1533 cmd += " --tcpSrc " + str( tcpSrc )
1534 if tcpDst:
1535 cmd += " --tcpDst " + str( tcpDst )
1536 if vlanId:
1537 cmd += " -v " + str( vlanId )
1538 if setVlan:
1539 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001540 if encap:
1541 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001542 if protected:
1543 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001544
kelvin8ec71442015-01-15 16:57:00 -08001545 # Check whether the user appended the port
1546 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001547 if "/" in ingressDevice:
1548 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001549 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001550 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001551 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001552 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001553 # Would it make sense to throw an exception and exit
1554 # the test?
1555 return None
andrewonlab36af3822014-11-18 17:48:18 -05001556
kelvin8ec71442015-01-15 16:57:00 -08001557 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001558 str( ingressDevice ) + "/" +\
1559 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001560
kelvin-onlabd3b64892015-01-20 13:26:24 -08001561 if "/" in egressDevice:
1562 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001563 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001564 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001565 main.log.error( "You must specify the egress port" )
1566 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001567
kelvin8ec71442015-01-15 16:57:00 -08001568 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001569 str( egressDevice ) + "/" +\
1570 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001571
kelvin-onlab898a6c62015-01-16 14:13:53 -08001572 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001573 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001574 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001575 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001576 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001577 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001578 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001579 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001580 # TODO: print out all the options in this message?
1581 main.log.info( "Point-to-point intent installed between " +
1582 str( ingressDevice ) + " and " +
1583 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001584 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001585 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001586 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001587 else:
1588 main.log.error( "Error, intent ID not found" )
1589 return None
Jon Hallc6793552016-01-19 14:18:37 -08001590 except AssertionError:
1591 main.log.exception( "" )
1592 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001593 except TypeError:
1594 main.log.exception( self.name + ": Object not as expected" )
1595 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001596 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001597 main.log.error( self.name + ": EOF exception found" )
1598 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001599 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001600 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001601 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001602 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001603
kelvin-onlabd3b64892015-01-20 13:26:24 -08001604 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001605 self,
shahshreyac2f97072015-03-19 17:04:29 -07001606 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001607 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001608 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001609 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001610 ethType="",
1611 ethSrc="",
1612 ethDst="",
1613 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001614 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001615 ipProto="",
1616 ipSrc="",
1617 ipDst="",
1618 tcpSrc="",
1619 tcpDst="",
1620 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001621 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001622 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001623 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001624 partial=False,
1625 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001626 """
shahshreyad0c80432014-12-04 16:56:05 -08001627 Note:
shahshreya70622b12015-03-19 17:19:00 -07001628 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001629 is same. That is, all ingress devices include port numbers
1630 with a "/" or all ingress devices could specify device
1631 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001632 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001633 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001634 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001635 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001636 Optional:
1637 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001638 * ethSrc: specify ethSrc ( i.e. src mac addr )
1639 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001640 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001641 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001642 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001643 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001644 * ipSrc: specify ip source address
1645 * ipDst: specify ip destination address
1646 * tcpSrc: specify tcp source port
1647 * tcpDst: specify tcp destination port
1648 * setEthSrc: action to Rewrite Source MAC Address
1649 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001650 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001651 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001652 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001653 Description:
kelvin8ec71442015-01-15 16:57:00 -08001654 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001655 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001656 Returns:
1657 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001658
Jon Halle3f39ff2015-01-13 11:50:53 -08001659 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001660 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001661 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001662 """
shahshreyad0c80432014-12-04 16:56:05 -08001663 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001664 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001665
Jeremy Songsterff553672016-05-12 17:06:23 -07001666 if ethType:
1667 cmd += " --ethType " + str( ethType )
1668 if ethSrc:
1669 cmd += " --ethSrc " + str( ethSrc )
1670 if ethDst:
1671 cmd += " --ethDst " + str( ethDst )
1672 if bandwidth:
1673 cmd += " --bandwidth " + str( bandwidth )
1674 if lambdaAlloc:
1675 cmd += " --lambda "
1676 if ipProto:
1677 cmd += " --ipProto " + str( ipProto )
1678 if ipSrc:
1679 cmd += " --ipSrc " + str( ipSrc )
1680 if ipDst:
1681 cmd += " --ipDst " + str( ipDst )
1682 if tcpSrc:
1683 cmd += " --tcpSrc " + str( tcpSrc )
1684 if tcpDst:
1685 cmd += " --tcpDst " + str( tcpDst )
1686 if setEthSrc:
1687 cmd += " --setEthSrc " + str( setEthSrc )
1688 if setEthDst:
1689 cmd += " --setEthDst " + str( setEthDst )
1690 if vlanId:
1691 cmd += " -v " + str( vlanId )
1692 if setVlan:
1693 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001694 if partial:
1695 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001696 if encap:
1697 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001698
kelvin8ec71442015-01-15 16:57:00 -08001699 # Check whether the user appended the port
1700 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001701
1702 if portIngressList is None:
1703 for ingressDevice in ingressDeviceList:
1704 if "/" in ingressDevice:
1705 cmd += " " + str( ingressDevice )
1706 else:
1707 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001708 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001709 # TODO: perhaps more meaningful return
1710 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001711 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001712 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001713 for ingressDevice, portIngress in zip( ingressDeviceList,
1714 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001715 cmd += " " + \
1716 str( ingressDevice ) + "/" +\
1717 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001718 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001719 main.log.error( "Device list and port list does not " +
1720 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001721 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001722 if "/" in egressDevice:
1723 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001724 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001725 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001726 main.log.error( "You must specify " +
1727 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001728 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001729
kelvin8ec71442015-01-15 16:57:00 -08001730 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001731 str( egressDevice ) + "/" +\
1732 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001733 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001734 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001735 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001736 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001737 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001738 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001739 "intent" )
1740 return None
shahshreyad0c80432014-12-04 16:56:05 -08001741 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001742 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001743 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001744 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001745 else:
1746 main.log.error( "Error, intent ID not found" )
1747 return None
Jon Hallc6793552016-01-19 14:18:37 -08001748 except AssertionError:
1749 main.log.exception( "" )
1750 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001751 except TypeError:
1752 main.log.exception( self.name + ": Object not as expected" )
1753 return None
1754 except pexpect.EOF:
1755 main.log.error( self.name + ": EOF exception found" )
1756 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001757 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001758 except Exception:
1759 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001760 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001761
1762 def addSinglepointToMultipointIntent(
1763 self,
1764 ingressDevice,
1765 egressDeviceList,
1766 portIngress="",
1767 portEgressList=None,
1768 ethType="",
1769 ethSrc="",
1770 ethDst="",
1771 bandwidth="",
1772 lambdaAlloc=False,
1773 ipProto="",
1774 ipSrc="",
1775 ipDst="",
1776 tcpSrc="",
1777 tcpDst="",
1778 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001779 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001780 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001781 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001782 partial=False,
1783 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001784 """
1785 Note:
1786 This function assumes the format of all egress devices
1787 is same. That is, all egress devices include port numbers
1788 with a "/" or all egress devices could specify device
1789 ids and port numbers seperately.
1790 Required:
1791 * EgressDeviceList: List of device ids of egress device
1792 ( Atleast 2 eress devices required in the list )
1793 * ingressDevice: device id of ingress device
1794 Optional:
1795 * ethType: specify ethType
1796 * ethSrc: specify ethSrc ( i.e. src mac addr )
1797 * ethDst: specify ethDst ( i.e. dst mac addr )
1798 * bandwidth: specify bandwidth capacity of link
1799 * lambdaAlloc: if True, intent will allocate lambda
1800 for the specified intent
1801 * ipProto: specify ip protocol
1802 * ipSrc: specify ip source address
1803 * ipDst: specify ip destination address
1804 * tcpSrc: specify tcp source port
1805 * tcpDst: specify tcp destination port
1806 * setEthSrc: action to Rewrite Source MAC Address
1807 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001808 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001809 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001810 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001811 Description:
1812 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1813 specifying device id's and optional fields
1814 Returns:
1815 A string of the intent id or None on error
1816
1817 NOTE: This function may change depending on the
1818 options developers provide for singlepoint-to-multipoint
1819 intent via cli
1820 """
1821 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001822 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001823
Jeremy Songsterff553672016-05-12 17:06:23 -07001824 if ethType:
1825 cmd += " --ethType " + str( ethType )
1826 if ethSrc:
1827 cmd += " --ethSrc " + str( ethSrc )
1828 if ethDst:
1829 cmd += " --ethDst " + str( ethDst )
1830 if bandwidth:
1831 cmd += " --bandwidth " + str( bandwidth )
1832 if lambdaAlloc:
1833 cmd += " --lambda "
1834 if ipProto:
1835 cmd += " --ipProto " + str( ipProto )
1836 if ipSrc:
1837 cmd += " --ipSrc " + str( ipSrc )
1838 if ipDst:
1839 cmd += " --ipDst " + str( ipDst )
1840 if tcpSrc:
1841 cmd += " --tcpSrc " + str( tcpSrc )
1842 if tcpDst:
1843 cmd += " --tcpDst " + str( tcpDst )
1844 if setEthSrc:
1845 cmd += " --setEthSrc " + str( setEthSrc )
1846 if setEthDst:
1847 cmd += " --setEthDst " + str( setEthDst )
1848 if vlanId:
1849 cmd += " -v " + str( vlanId )
1850 if setVlan:
1851 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001852 if partial:
1853 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001854 if encap:
1855 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001856
1857 # Check whether the user appended the port
1858 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001859
kelvin-onlabb9408212015-04-01 13:34:04 -07001860 if "/" in ingressDevice:
1861 cmd += " " + str( ingressDevice )
1862 else:
1863 if not portIngress:
1864 main.log.error( "You must specify " +
1865 "the Ingress port" )
1866 return main.FALSE
1867
1868 cmd += " " +\
1869 str( ingressDevice ) + "/" +\
1870 str( portIngress )
1871
1872 if portEgressList is None:
1873 for egressDevice in egressDeviceList:
1874 if "/" in egressDevice:
1875 cmd += " " + str( egressDevice )
1876 else:
1877 main.log.error( "You must specify " +
1878 "the egress port" )
1879 # TODO: perhaps more meaningful return
1880 return main.FALSE
1881 else:
1882 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001883 for egressDevice, portEgress in zip( egressDeviceList,
1884 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001885 cmd += " " + \
1886 str( egressDevice ) + "/" +\
1887 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001888 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001889 main.log.error( "Device list and port list does not " +
1890 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001891 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001892 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001893 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001894 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001895 # If error, return error message
1896 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001897 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001898 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001899 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001900 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001901 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001902 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001903 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001904 else:
1905 main.log.error( "Error, intent ID not found" )
1906 return None
Jon Hallc6793552016-01-19 14:18:37 -08001907 except AssertionError:
1908 main.log.exception( "" )
1909 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001910 except TypeError:
1911 main.log.exception( self.name + ": Object not as expected" )
1912 return None
shahshreyad0c80432014-12-04 16:56:05 -08001913 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001914 main.log.error( self.name + ": EOF exception found" )
1915 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001916 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001917 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001918 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001919 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001920
Hari Krishna9e232602015-04-13 17:29:08 -07001921 def addMplsIntent(
1922 self,
1923 ingressDevice,
1924 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001925 ingressPort="",
1926 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001927 ethType="",
1928 ethSrc="",
1929 ethDst="",
1930 bandwidth="",
1931 lambdaAlloc=False,
1932 ipProto="",
1933 ipSrc="",
1934 ipDst="",
1935 tcpSrc="",
1936 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001937 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001938 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001939 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001940 """
1941 Required:
1942 * ingressDevice: device id of ingress device
1943 * egressDevice: device id of egress device
1944 Optional:
1945 * ethType: specify ethType
1946 * ethSrc: specify ethSrc ( i.e. src mac addr )
1947 * ethDst: specify ethDst ( i.e. dst mac addr )
1948 * bandwidth: specify bandwidth capacity of link
1949 * lambdaAlloc: if True, intent will allocate lambda
1950 for the specified intent
1951 * ipProto: specify ip protocol
1952 * ipSrc: specify ip source address
1953 * ipDst: specify ip destination address
1954 * tcpSrc: specify tcp source port
1955 * tcpDst: specify tcp destination port
1956 * ingressLabel: Ingress MPLS label
1957 * egressLabel: Egress MPLS label
1958 Description:
1959 Adds MPLS intent by
1960 specifying device id's and optional fields
1961 Returns:
1962 A string of the intent id or None on error
1963
1964 NOTE: This function may change depending on the
1965 options developers provide for MPLS
1966 intent via cli
1967 """
1968 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001969 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001970
Jeremy Songsterff553672016-05-12 17:06:23 -07001971 if ethType:
1972 cmd += " --ethType " + str( ethType )
1973 if ethSrc:
1974 cmd += " --ethSrc " + str( ethSrc )
1975 if ethDst:
1976 cmd += " --ethDst " + str( ethDst )
1977 if bandwidth:
1978 cmd += " --bandwidth " + str( bandwidth )
1979 if lambdaAlloc:
1980 cmd += " --lambda "
1981 if ipProto:
1982 cmd += " --ipProto " + str( ipProto )
1983 if ipSrc:
1984 cmd += " --ipSrc " + str( ipSrc )
1985 if ipDst:
1986 cmd += " --ipDst " + str( ipDst )
1987 if tcpSrc:
1988 cmd += " --tcpSrc " + str( tcpSrc )
1989 if tcpDst:
1990 cmd += " --tcpDst " + str( tcpDst )
1991 if ingressLabel:
1992 cmd += " --ingressLabel " + str( ingressLabel )
1993 if egressLabel:
1994 cmd += " --egressLabel " + str( egressLabel )
1995 if priority:
1996 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001997
1998 # Check whether the user appended the port
1999 # or provided it as an input
2000 if "/" in ingressDevice:
2001 cmd += " " + str( ingressDevice )
2002 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002003 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002004 main.log.error( "You must specify the ingress port" )
2005 return None
2006
2007 cmd += " " + \
2008 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002009 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07002010
2011 if "/" in egressDevice:
2012 cmd += " " + str( egressDevice )
2013 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002014 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002015 main.log.error( "You must specify the egress port" )
2016 return None
2017
2018 cmd += " " +\
2019 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002020 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07002021
2022 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08002023 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002024 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07002025 # If error, return error message
2026 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002027 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07002028 return None
2029 else:
2030 # TODO: print out all the options in this message?
2031 main.log.info( "MPLS intent installed between " +
2032 str( ingressDevice ) + " and " +
2033 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002034 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07002035 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002036 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07002037 else:
2038 main.log.error( "Error, intent ID not found" )
2039 return None
Jon Hallc6793552016-01-19 14:18:37 -08002040 except AssertionError:
2041 main.log.exception( "" )
2042 return None
Hari Krishna9e232602015-04-13 17:29:08 -07002043 except TypeError:
2044 main.log.exception( self.name + ": Object not as expected" )
2045 return None
2046 except pexpect.EOF:
2047 main.log.error( self.name + ": EOF exception found" )
2048 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002049 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002050 except Exception:
2051 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002052 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002053
Jon Hallefbd9792015-03-05 16:11:36 -08002054 def removeIntent( self, intentId, app='org.onosproject.cli',
2055 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002056 """
shahshreya1c818fc2015-02-26 13:44:08 -08002057 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07002058 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08002059 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07002060 -p or --purge: Purge the intent from the store after removal
2061
Jon Halle3f39ff2015-01-13 11:50:53 -08002062 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002063 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002064 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002065 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002066 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002067 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002068 if purge:
2069 cmdStr += " -p"
2070 if sync:
2071 cmdStr += " -s"
2072
2073 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002074 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002075 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002076 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002077 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002078 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002079 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002080 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002081 # TODO: Should this be main.TRUE
2082 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002083 except AssertionError:
2084 main.log.exception( "" )
2085 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002086 except TypeError:
2087 main.log.exception( self.name + ": Object not as expected" )
2088 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002089 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002090 main.log.error( self.name + ": EOF exception found" )
2091 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002092 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002093 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002094 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002095 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002096
YPZhangfebf7302016-05-24 16:45:56 -07002097 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002098 """
2099 Description:
2100 Remove all the intents
2101 Optional args:-
2102 -s or --sync: Waits for the removal before returning
2103 -p or --purge: Purge the intent from the store after removal
2104 Returns:
2105 Returns main.TRUE if all intents are removed, otherwise returns
2106 main.FALSE; Returns None for exception
2107 """
2108 try:
2109 cmdStr = "remove-intent"
2110 if purge:
2111 cmdStr += " -p"
2112 if sync:
2113 cmdStr += " -s"
2114
2115 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002116 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002117 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002118 assert "Command not found:" not in handle, handle
2119 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002120 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002121 return main.FALSE
2122 else:
2123 return main.TRUE
2124 except AssertionError:
2125 main.log.exception( "" )
2126 return None
2127 except TypeError:
2128 main.log.exception( self.name + ": Object not as expected" )
2129 return None
2130 except pexpect.EOF:
2131 main.log.error( self.name + ": EOF exception found" )
2132 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002133 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002134 except Exception:
2135 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002136 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002137
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002138 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002139 """
2140 Purges all WITHDRAWN Intents
2141 """
2142 try:
2143 cmdStr = "purge-intents"
2144 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002145 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002146 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002147 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002148 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002149 return main.FALSE
2150 else:
2151 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002152 except AssertionError:
2153 main.log.exception( "" )
2154 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002155 except TypeError:
2156 main.log.exception( self.name + ": Object not as expected" )
2157 return None
2158 except pexpect.EOF:
2159 main.log.error( self.name + ": EOF exception found" )
2160 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002161 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002162 except Exception:
2163 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002164 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002165
Devin Lime6fe3c42017-10-18 16:28:40 -07002166 def wipeout( self ):
2167 """
2168 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2169 """
2170 try:
2171 cmdStr = "wipe-out please"
2172 handle = self.sendline( cmdStr, timeout=60 )
2173 assert handle is not None, "Error in sendline"
2174 assert "Command not found:" not in handle, handle
2175 return main.TRUE
2176 except AssertionError:
2177 main.log.exception( "" )
2178 return None
2179 except TypeError:
2180 main.log.exception( self.name + ": Object not as expected" )
2181 return None
2182 except pexpect.EOF:
2183 main.log.error( self.name + ": EOF exception found" )
2184 main.log.error( self.name + ": " + self.handle.before )
2185 main.cleanAndExit()
2186 except Exception:
2187 main.log.exception( self.name + ": Uncaught exception!" )
2188 main.cleanAndExit()
2189
kelvin-onlabd3b64892015-01-20 13:26:24 -08002190 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002191 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002192 NOTE: This method should be used after installing application:
2193 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002194 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002195 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002196 Description:
2197 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002198 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002199 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002200 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002201 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002202 cmdStr += " -j"
2203 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002204 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002205 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002206 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002207 except AssertionError:
2208 main.log.exception( "" )
2209 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002210 except TypeError:
2211 main.log.exception( self.name + ": Object not as expected" )
2212 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002213 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002214 main.log.error( self.name + ": EOF exception found" )
2215 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002216 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002217 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002218 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002219 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002220
pingping-lin54b03372015-08-13 14:43:10 -07002221 def ipv4RouteNumber( self ):
2222 """
2223 NOTE: This method should be used after installing application:
2224 onos-app-sdnip
2225 Description:
2226 Obtain the total IPv4 routes number in the system
2227 """
2228 try:
Pratik Parab57963572017-05-09 11:37:54 -07002229 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002230 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002231 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002232 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002233 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002234 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002235 except AssertionError:
2236 main.log.exception( "" )
2237 return None
2238 except ( TypeError, ValueError ):
2239 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002240 return None
2241 except pexpect.EOF:
2242 main.log.error( self.name + ": EOF exception found" )
2243 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002244 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002245 except Exception:
2246 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002247 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002248
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002249 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002250 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002251 """
2252 Description:
2253 Obtain Bandwidth Allocation Information from ONOS cli.
2254 """
2255 try:
2256 cmdStr = "allocations"
2257 if jsonFormat:
2258 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002259 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002260 assert handle is not None, "Error in sendline"
2261 assert "Command not found:" not in handle, handle
2262 return handle
2263 except AssertionError:
2264 main.log.exception( "" )
2265 return None
2266 except ( TypeError, ValueError ):
2267 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2268 return None
2269 except pexpect.EOF:
2270 main.log.error( self.name + ": EOF exception found" )
2271 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002272 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002273 except Exception:
2274 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002275 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002276
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002277 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002278 """
andrewonlabe6745342014-10-17 14:29:13 -04002279 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002280 Obtain intents from the ONOS cli.
2281 Optional:
2282 * jsonFormat: Enable output formatting in json, default to True
2283 * summary: Whether only output the intent summary, defaults to False
2284 * type: Only output a certain type of intent. This options is valid
2285 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002286 """
andrewonlabe6745342014-10-17 14:29:13 -04002287 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002288 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002289 if summary:
2290 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002291 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002292 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002293 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002294 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002295 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002296 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002297 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002298 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002299 else:
Jon Hallff566d52016-01-15 14:45:36 -08002300 intentType = ""
2301 # IF we want the summary of a specific intent type
2302 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002303 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002304 if intentType in jsonResult.keys():
2305 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002306 else:
Jon Hallff566d52016-01-15 14:45:36 -08002307 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002308 return handle
2309 else:
2310 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002311 except AssertionError:
2312 main.log.exception( "" )
2313 return None
2314 except ( TypeError, ValueError ):
2315 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002316 return None
2317 except pexpect.EOF:
2318 main.log.error( self.name + ": EOF exception found" )
2319 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002320 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002321 except Exception:
2322 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002323 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002324
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002325 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002326 """
You Wangfdcbfc42016-05-16 12:16:53 -07002327 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002328 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002329 list of intent IDs.
2330 Parameters:
2331 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002332 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002333 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002334 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002335 accepted.
2336 Returns a list of dictionaries if a list of intent IDs is accepted,
2337 and each dictionary maps 'id' to the Intent ID and 'state' to
2338 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002339 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002340
kelvin-onlab54400a92015-02-26 18:05:51 -08002341 try:
2342 state = "State is Undefined"
2343 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002344 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002345 else:
Jon Hallc6793552016-01-19 14:18:37 -08002346 rawJson = intentsJson
2347 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002348 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002349 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002350 if intentsId == intent[ 'id' ]:
2351 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002352 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002353 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002354 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002355 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002356 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002357 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002358 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002359 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002360 for intent in parsedIntentsJson:
2361 if intentsId[ i ] == intent[ 'id' ]:
2362 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002363 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002364 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002365 break
Jon Hallefbd9792015-03-05 16:11:36 -08002366 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002367 main.log.warn( "Could not find all intents in ONOS output" )
2368 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002369 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002370 else:
Jon Hall53158082017-05-18 11:17:00 -07002371 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002372 return None
Jon Hallc6793552016-01-19 14:18:37 -08002373 except ( TypeError, ValueError ):
2374 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002375 return None
2376 except pexpect.EOF:
2377 main.log.error( self.name + ": EOF exception found" )
2378 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002379 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002380 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002381 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002382 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002383
Jon Hallf539eb92017-05-22 17:18:42 -07002384 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002385 """
2386 Description:
2387 Check intents state
2388 Required:
2389 intentsId - List of intents ID to be checked
2390 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002391 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002392 state in the list.
2393 *NOTE: You can pass in a list of expected state,
2394 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002395 Return:
Jon Hall53158082017-05-18 11:17:00 -07002396 Returns main.TRUE only if all intent are the same as expected states,
2397 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002398 """
2399 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002400 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002401 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002402
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002403 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002404 intentsDict = []
2405 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002406 if isinstance( intentsId, types.StringType ) \
2407 and intent.get( 'id' ) == intentsId:
2408 intentsDict.append( intent )
2409 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002410 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002411 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002412
2413 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002414 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002415 "getting intents state" )
2416 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002417
2418 if isinstance( expectedState, types.StringType ):
2419 for intents in intentsDict:
2420 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002421 main.log.debug( self.name + " : Intent ID - " +
2422 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002423 " actual state = " +
2424 intents.get( 'state' )
2425 + " does not equal expected state = "
2426 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002427 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002428 elif isinstance( expectedState, types.ListType ):
2429 for intents in intentsDict:
2430 if not any( state == intents.get( 'state' ) for state in
2431 expectedState ):
2432 main.log.debug( self.name + " : Intent ID - " +
2433 intents.get( 'id' ) +
2434 " actual state = " +
2435 intents.get( 'state' ) +
2436 " does not equal expected states = "
2437 + str( expectedState ) )
2438 returnValue = main.FALSE
2439
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002440 if returnValue == main.TRUE:
2441 main.log.info( self.name + ": All " +
2442 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002443 " intents are in " + str( expectedState ) +
2444 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002445 return returnValue
2446 except TypeError:
2447 main.log.exception( self.name + ": Object not as expected" )
2448 return None
2449 except pexpect.EOF:
2450 main.log.error( self.name + ": EOF exception found" )
2451 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002452 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002453 except Exception:
2454 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002455 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002456
Jon Hallf539eb92017-05-22 17:18:42 -07002457 def compareBandwidthAllocations( self, expectedAllocations ):
2458 """
2459 Description:
2460 Compare the allocated bandwidth with the given allocations
2461 Required:
2462 expectedAllocations - The expected ONOS output of the allocations command
2463 Return:
2464 Returns main.TRUE only if all intent are the same as expected states,
2465 otherwise returns main.FALSE.
2466 """
2467 # FIXME: Convert these string comparisons to object comparisons
2468 try:
2469 returnValue = main.TRUE
2470 bandwidthFailed = False
2471 rawAlloc = self.allocations()
2472 expectedFormat = StringIO( expectedAllocations )
2473 ONOSOutput = StringIO( rawAlloc )
2474 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2475 str( expectedFormat ) ) )
2476
2477 for actual, expected in izip( ONOSOutput, expectedFormat ):
2478 actual = actual.rstrip()
2479 expected = expected.rstrip()
2480 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2481 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002482 marker1 = actual.find( 'allocated' )
2483 m1 = actual[ :marker1 ]
2484 marker2 = expected.find( 'allocated' )
2485 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002486 if m1 != m2:
2487 bandwidthFailed = True
2488 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2489 bandwidthFailed = True
2490 expectedFormat.close()
2491 ONOSOutput.close()
2492
2493 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002494 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002495 returnValue = main.FALSE
2496 return returnValue
2497 except TypeError:
2498 main.log.exception( self.name + ": Object not as expected" )
2499 return None
2500 except pexpect.EOF:
2501 main.log.error( self.name + ": EOF exception found" )
2502 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002503 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002504 except Exception:
2505 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002506 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002507
You Wang66518af2016-05-16 15:32:59 -07002508 def compareIntent( self, intentDict ):
2509 """
2510 Description:
2511 Compare the intent ids and states provided in the argument with all intents in ONOS
2512 Return:
2513 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2514 Arguments:
2515 intentDict: a dictionary which maps intent ids to intent states
2516 """
2517 try:
2518 intentsRaw = self.intents()
2519 intentsJson = json.loads( intentsRaw )
2520 intentDictONOS = {}
2521 for intent in intentsJson:
2522 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002523 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002524 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002525 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002526 str( len( intentDict ) ) + " expected and " +
2527 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002528 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002529 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002530 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002531 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2532 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002533 else:
2534 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2535 main.log.debug( self.name + ": intent ID - " + intentID +
2536 " expected state is " + intentDict[ intentID ] +
2537 " but actual state is " + intentDictONOS[ intentID ] )
2538 returnValue = main.FALSE
2539 intentDictONOS.pop( intentID )
2540 if len( intentDictONOS ) > 0:
2541 returnValue = main.FALSE
2542 for intentID in intentDictONOS.keys():
2543 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002544 if returnValue == main.TRUE:
2545 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2546 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002547 except KeyError:
2548 main.log.exception( self.name + ": KeyError exception found" )
2549 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002550 except ( TypeError, ValueError ):
2551 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002552 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002553 except pexpect.EOF:
2554 main.log.error( self.name + ": EOF exception found" )
2555 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002556 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002557 except Exception:
2558 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002559 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002560
YPZhang14a4aa92016-07-15 13:37:15 -07002561 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002562 """
2563 Description:
2564 Check the number of installed intents.
2565 Optional:
2566 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002567 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002568 Return:
2569 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2570 , otherwise, returns main.FALSE.
2571 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002572
GlennRCed771242016-01-13 17:02:47 -08002573 try:
2574 cmd = "intents -s -j"
2575
2576 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002577 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002578 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002579 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002580 response = json.loads( response )
2581
2582 # get total and installed number, see if they are match
2583 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002584 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002585 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2586 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002587 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002588 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2589 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002590 return main.FALSE
2591
Jon Hallc6793552016-01-19 14:18:37 -08002592 except ( TypeError, ValueError ):
2593 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002594 return None
2595 except pexpect.EOF:
2596 main.log.error( self.name + ": EOF exception found" )
2597 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002598 if noExit:
2599 return main.FALSE
2600 else:
Devin Lim44075962017-08-11 10:56:37 -07002601 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002602 except pexpect.TIMEOUT:
2603 main.log.error( self.name + ": ONOS timeout" )
2604 return None
GlennRCed771242016-01-13 17:02:47 -08002605 except Exception:
2606 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002607 if noExit:
2608 return main.FALSE
2609 else:
Devin Lim44075962017-08-11 10:56:37 -07002610 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002611
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002612 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002613 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002614 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002615 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002616 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002617 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002618 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002619 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002620 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002621 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002622 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002623 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002624 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002625 cmdStr += " -n"
2626 cmdStr += " " + state
2627 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002628 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002629 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002630 assert "Command not found:" not in handle, handle
2631 if re.search( "Error:", handle ):
2632 main.log.error( self.name + ": flows() response: " +
2633 str( handle ) )
2634 return handle
2635 except AssertionError:
2636 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002637 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002638 except TypeError:
2639 main.log.exception( self.name + ": Object not as expected" )
2640 return None
Jon Hallc6793552016-01-19 14:18:37 -08002641 except pexpect.TIMEOUT:
2642 main.log.error( self.name + ": ONOS timeout" )
2643 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002644 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002645 main.log.error( self.name + ": EOF exception found" )
2646 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002647 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002648 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002649 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002650 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002651
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002652 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002653 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002654 count = int( count ) if count else 0
2655 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002656
Jon Halle0f0b342017-04-18 11:43:47 -07002657 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002658 """
2659 Description:
GlennRCed771242016-01-13 17:02:47 -08002660 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002661 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2662 if the count of those states is 0, which means all current flows
2663 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002664 Optional:
GlennRCed771242016-01-13 17:02:47 -08002665 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002666 Return:
2667 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002668 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002669 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002670 """
2671 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002672 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002673 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002674 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002675 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002676 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002677 if rawFlows:
2678 # if we didn't get flows or flows function return None, we should return
2679 # main.Flase
2680 checkedStates.append( json.loads( rawFlows ) )
2681 else:
2682 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002683 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002684 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002685 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002686 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002687 except TypeError:
2688 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002689 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002690
GlennRCed771242016-01-13 17:02:47 -08002691 # We want to count PENDING_ADD if isPENDING is true
2692 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002693 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002694 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002695 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002696 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002697 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002698 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002699 except ( TypeError, ValueError ):
2700 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002701 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002702
YPZhang240842b2016-05-17 12:00:50 -07002703 except AssertionError:
2704 main.log.exception( "" )
2705 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002706 except pexpect.TIMEOUT:
2707 main.log.error( self.name + ": ONOS timeout" )
2708 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002709 except pexpect.EOF:
2710 main.log.error( self.name + ": EOF exception found" )
2711 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002712 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002713 except Exception:
2714 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002715 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002716
GlennRCed771242016-01-13 17:02:47 -08002717 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002718 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002719 """
andrewonlab87852b02014-11-19 18:44:19 -05002720 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002721 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002722 a specific point-to-point intent definition
2723 Required:
GlennRCed771242016-01-13 17:02:47 -08002724 * ingress: specify source dpid
2725 * egress: specify destination dpid
2726 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002727 Optional:
GlennRCed771242016-01-13 17:02:47 -08002728 * offset: the keyOffset is where the next batch of intents
2729 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002730 * noExit: If set to True, TestON will not exit if any error when issus command
2731 * getResponse: If set to True, function will return ONOS response.
2732
GlennRCed771242016-01-13 17:02:47 -08002733 Returns: If failed to push test intents, it will returen None,
2734 if successful, return true.
2735 Timeout expection will return None,
2736 TypeError will return false
2737 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002738 """
andrewonlab87852b02014-11-19 18:44:19 -05002739 try:
GlennRCed771242016-01-13 17:02:47 -08002740 if background:
2741 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002742 else:
GlennRCed771242016-01-13 17:02:47 -08002743 back = ""
2744 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002745 ingress,
2746 egress,
2747 batchSize,
2748 offset,
2749 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002750 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002751 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002752 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002753 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002754 if getResponse:
2755 return response
2756
GlennRCed771242016-01-13 17:02:47 -08002757 # TODO: We should handle if there is failure in installation
2758 return main.TRUE
2759
Jon Hallc6793552016-01-19 14:18:37 -08002760 except AssertionError:
2761 main.log.exception( "" )
2762 return None
GlennRCed771242016-01-13 17:02:47 -08002763 except pexpect.TIMEOUT:
2764 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002765 return None
andrewonlab87852b02014-11-19 18:44:19 -05002766 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002767 main.log.error( self.name + ": EOF exception found" )
2768 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002769 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002770 except TypeError:
2771 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002772 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002773 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002774 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002775 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002776
YPZhangebf9eb52016-05-12 15:20:24 -07002777 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002778 """
2779 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002780 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002781 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002782 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002783 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002784 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002785
YPZhangb5d3f832016-01-23 22:54:26 -08002786 try:
YPZhange3109a72016-02-02 11:25:37 -08002787 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002788 cmd = "flows -c added"
2789 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2790 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002791 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002792 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002793 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002794 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002795 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002796 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002797 return None
2798 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002799
You Wangd3cb2ce2016-05-16 14:01:24 -07002800 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002801 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002802 return None
2803 except pexpect.EOF:
2804 main.log.error( self.name + ": EOF exception found" )
2805 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002806 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002807 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002808 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002809 except pexpect.TIMEOUT:
2810 main.log.error( self.name + ": ONOS timeout" )
2811 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002812 except Exception:
2813 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002814 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002815 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002816 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002817
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002818 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002819 """
2820 Description:
2821 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002822 Optional:
2823 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002824 Return:
2825 The number of intents
2826 """
2827 try:
2828 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002829 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002830 if response is None:
2831 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002832 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002833 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002834 except ( TypeError, ValueError ):
2835 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002836 return None
2837 except pexpect.EOF:
2838 main.log.error( self.name + ": EOF exception found" )
2839 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002840 if noExit:
2841 return -1
2842 else:
Devin Lim44075962017-08-11 10:56:37 -07002843 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002844 except Exception:
2845 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002846 if noExit:
2847 return -1
2848 else:
Devin Lim44075962017-08-11 10:56:37 -07002849 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002850
kelvin-onlabd3b64892015-01-20 13:26:24 -08002851 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002852 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002853 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002854 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002855 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002856 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002857 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002858 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002859 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002860 cmdStr += " -j"
2861 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002862 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002863 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002864 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002865 except AssertionError:
2866 main.log.exception( "" )
2867 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002868 except TypeError:
2869 main.log.exception( self.name + ": Object not as expected" )
2870 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002871 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002872 main.log.error( self.name + ": EOF exception found" )
2873 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002874 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002875 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002876 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002877 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002878
kelvin-onlabd3b64892015-01-20 13:26:24 -08002879 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002880 """
2881 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002882 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002883 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002884 """
andrewonlab867212a2014-10-22 20:13:38 -04002885 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002886 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002887 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002888 cmdStr += " -j"
2889 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002890 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002891 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002892 if handle:
2893 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002894 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002895 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002896 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002897 else:
2898 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002899 except AssertionError:
2900 main.log.exception( "" )
2901 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002902 except TypeError:
2903 main.log.exception( self.name + ": Object not as expected" )
2904 return None
andrewonlab867212a2014-10-22 20:13:38 -04002905 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002906 main.log.error( self.name + ": EOF exception found" )
2907 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002908 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002909 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002910 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002911 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002912
kelvin8ec71442015-01-15 16:57:00 -08002913 # Wrapper functions ****************
2914 # Wrapper functions use existing driver
2915 # functions and extends their use case.
2916 # For example, we may use the output of
2917 # a normal driver function, and parse it
2918 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002919
kelvin-onlabd3b64892015-01-20 13:26:24 -08002920 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002921 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002922 Description:
2923 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002924 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002925 try:
kelvin8ec71442015-01-15 16:57:00 -08002926 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002927 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002928 if intentsStr is None:
2929 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002930 # Convert to a dictionary
2931 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002932 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002933 for intent in intents:
2934 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002935 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002936 except TypeError:
2937 main.log.exception( self.name + ": Object not as expected" )
2938 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002939 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002940 main.log.error( self.name + ": EOF exception found" )
2941 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002942 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002943 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002944 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002945 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002946
You Wang3c276252016-09-21 15:21:36 -07002947 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002948 """
2949 Determine the number of flow rules for the given device id that are
2950 in the added state
You Wang3c276252016-09-21 15:21:36 -07002951 Params:
2952 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002953 """
2954 try:
You Wang3c276252016-09-21 15:21:36 -07002955 if core:
2956 cmdStr = "flows any " + str( deviceId ) + " | " +\
2957 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2958 else:
2959 cmdStr = "flows any " + str( deviceId ) + " | " +\
2960 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08002961 handle = self.lineCount( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002962 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002963 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002964 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002965 except AssertionError:
2966 main.log.exception( "" )
2967 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002968 except pexpect.EOF:
2969 main.log.error( self.name + ": EOF exception found" )
2970 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002971 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002972 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002973 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002974 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002975
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002976 def groupAddedCount( self, deviceId, core=False ):
2977 """
2978 Determine the number of group rules for the given device id that are
2979 in the added state
2980 Params:
2981 core: if True, only return the number of core groups added
2982 """
2983 try:
2984 if core:
2985 cmdStr = "groups any " + str( deviceId ) + " | " +\
2986 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2987 else:
2988 cmdStr = "groups any " + str( deviceId ) + " | " +\
2989 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08002990 handle = self.lineCount( cmdStr )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002991 assert handle is not None, "Error in sendline"
2992 assert "Command not found:" not in handle, handle
2993 return handle
2994 except AssertionError:
2995 main.log.exception( "" )
2996 return None
2997 except pexpect.EOF:
2998 main.log.error( self.name + ": EOF exception found" )
2999 main.log.error( self.name + ": " + self.handle.before )
3000 main.cleanAndExit()
3001 except Exception:
3002 main.log.exception( self.name + ": Uncaught exception!" )
3003 main.cleanAndExit()
3004
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003005 def addStaticRoute( self, subnet, intf):
3006 """
3007 Adds a static route to onos.
3008 Params:
3009 subnet: The subnet reaching through this route
3010 intf: The interface this route is reachable through
3011 """
3012 try:
3013 cmdStr = "route-add " + subnet + " " + intf
3014 handle = self.sendline( cmdStr )
3015 assert handle is not None, "Error in sendline"
3016 assert "Command not found:" not in handle, handle
3017 return handle
3018 except AssertionError:
3019 main.log.exception( "" )
3020 return None
3021 except pexpect.EOF:
3022 main.log.error( self.name + ": EOF exception found" )
3023 main.log.error( self.name + ": " + self.handle.before )
3024 main.cleanAndExit()
3025 except Exception:
3026 main.log.exception( self.name + ": Uncaught exception!" )
3027 main.cleanAndExit()
3028
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003029 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
3030 """
3031 Description:
3032 Check whether the number of groups for the given device id that
3033 are in ADDED state is bigger than minGroupCount.
3034 Required:
3035 * deviceId: device id to check the number of added group rules
3036 Optional:
3037 * minGroupCount: the number of groups to compare
3038 * core: if True, only check the number of core groups added
3039 * comparison: if 0, compare with greater than minFlowCount
3040 * if 1, compare with equal to minFlowCount
3041 Return:
3042 Returns the number of groups if it is bigger than minGroupCount,
3043 returns main.FALSE otherwise.
3044 """
3045 count = self.groupAddedCount( deviceId, core )
3046 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003047 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003048 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
3049
You Wangc02f3be2018-05-18 12:14:23 -07003050 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003051 """
3052 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07003053 deviceId: Id of the device from which we retrieve groups
3054 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003055 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003056 try:
You Wangc02f3be2018-05-18 12:14:23 -07003057 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
3058 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003059 assert handle is not None, "Error in sendline"
3060 assert "Command not found:" not in handle, handle
3061 return handle
3062 except AssertionError:
3063 main.log.exception( "" )
3064 return None
3065 except TypeError:
3066 main.log.exception( self.name + ": Object not as expected" )
3067 return None
3068 except pexpect.EOF:
3069 main.log.error( self.name + ": EOF exception found" )
3070 main.log.error( self.name + ": " + self.handle.before )
3071 main.cleanAndExit()
3072 except Exception:
3073 main.log.exception( self.name + ": Uncaught exception!" )
3074 main.cleanAndExit()
3075
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003076 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003077 """
3078 Description:
3079 Check whether the number of flow rules for the given device id that
3080 are in ADDED state is bigger than minFlowCount.
3081 Required:
3082 * deviceId: device id to check the number of added flow rules
3083 Optional:
3084 * minFlowCount: the number of flow rules to compare
3085 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003086 * comparison: if 0, compare with greater than minFlowCount
3087 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003088 Return:
3089 Returns the number of flow rules if it is bigger than minFlowCount,
3090 returns main.FALSE otherwise.
3091 """
3092 count = self.flowAddedCount( deviceId, core )
3093 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003094 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003095 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003096
kelvin-onlabd3b64892015-01-20 13:26:24 -08003097 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003098 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003099 Use 'devices' function to obtain list of all devices
3100 and parse the result to obtain a list of all device
3101 id's. Returns this list. Returns empty list if no
3102 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003103 List is ordered sequentially
3104
andrewonlab3e15ead2014-10-15 14:21:34 -04003105 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003106 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003107 the ids. By obtaining the list of device ids on the fly,
3108 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003109 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003110 try:
kelvin8ec71442015-01-15 16:57:00 -08003111 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003112 devicesStr = self.devices( jsonFormat=False )
3113 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003114
kelvin-onlabd3b64892015-01-20 13:26:24 -08003115 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003116 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003117 return idList
kelvin8ec71442015-01-15 16:57:00 -08003118
3119 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003120 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003121 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003122 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003123 # Split list further into arguments before and after string
3124 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003125 # append to idList
3126 for arg in tempList:
3127 idList.append( arg.split( "id=" )[ 1 ] )
3128 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003129
Jon Halld4d4b372015-01-28 16:02:41 -08003130 except TypeError:
3131 main.log.exception( self.name + ": Object not as expected" )
3132 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003133 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003134 main.log.error( self.name + ": EOF exception found" )
3135 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003136 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003137 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003138 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003139 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003140
kelvin-onlabd3b64892015-01-20 13:26:24 -08003141 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003142 """
andrewonlab7c211572014-10-15 16:45:20 -04003143 Uses 'nodes' function to obtain list of all nodes
3144 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003145 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003146 Returns:
3147 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003148 """
andrewonlab7c211572014-10-15 16:45:20 -04003149 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003150 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003151 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003152 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003153 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003154 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003155 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003156 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003157 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003158 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003159 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003160 except ( TypeError, ValueError ):
3161 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003162 return None
andrewonlab7c211572014-10-15 16:45:20 -04003163 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003164 main.log.error( self.name + ": EOF exception found" )
3165 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003166 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003167 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003168 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003169 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003170
kelvin-onlabd3b64892015-01-20 13:26:24 -08003171 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003172 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003173 Return the first device from the devices api whose 'id' contains 'dpid'
3174 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003175 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003176 try:
kelvin8ec71442015-01-15 16:57:00 -08003177 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003178 return None
3179 else:
kelvin8ec71442015-01-15 16:57:00 -08003180 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003181 rawDevices = self.devices()
3182 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003183 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003184 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003185 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3186 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003187 return device
3188 return None
Jon Hallc6793552016-01-19 14:18:37 -08003189 except ( TypeError, ValueError ):
3190 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003191 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003192 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003193 main.log.error( self.name + ": EOF exception found" )
3194 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003195 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003196 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003197 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003198 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003199
You Wang24139872016-05-03 11:48:47 -07003200 def getTopology( self, topologyOutput ):
3201 """
3202 Definition:
3203 Loads a json topology output
3204 Return:
3205 topology = current ONOS topology
3206 """
3207 import json
3208 try:
3209 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003210 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003211 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003212 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003213 except ( TypeError, ValueError ):
3214 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3215 return None
You Wang24139872016-05-03 11:48:47 -07003216 except pexpect.EOF:
3217 main.log.error( self.name + ": EOF exception found" )
3218 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003219 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003220 except Exception:
3221 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003222 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003223
Pier6a0c4de2018-03-18 16:01:30 -07003224 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003225 """
Jon Hallefbd9792015-03-05 16:11:36 -08003226 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003227 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003228 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003229
Flavio Castro82ee2f62016-06-07 15:04:12 -07003230 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003231 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003232 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003233 logLevel = level to log to.
3234 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003235
Jon Hallefbd9792015-03-05 16:11:36 -08003236 Returns: main.TRUE if the number of switches and links are correct,
3237 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003238 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003239 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003240 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003241 try:
You Wang13310252016-07-31 10:56:14 -07003242 summary = self.summary()
3243 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003244 except ( TypeError, ValueError ):
3245 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3246 return main.ERROR
3247 try:
3248 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003249 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003250 return main.ERROR
3251 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003252 # Is the number of switches is what we expected
3253 devices = topology.get( 'devices', False )
3254 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003255 nodes = summary.get( 'nodes', False )
3256 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003257 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003258 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003259 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003260 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003261 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3262 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003263 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003264 output = output + "The number of links and switches match "\
3265 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003266 result = main.TRUE
3267 else:
You Wang24139872016-05-03 11:48:47 -07003268 output = output + \
3269 "The number of links and switches does not match " + \
3270 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003271 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003272 output = output + "\n ONOS sees %i devices" % int( devices )
3273 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003274 if int( numolink ) > 0:
3275 output = output + "and %i links " % int( links )
3276 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003277 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003278 output = output + "and %i controllers " % int( nodes )
3279 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003280 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003281 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003282 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003283 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003284 else:
You Wang24139872016-05-03 11:48:47 -07003285 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003286 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003287 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003288 main.log.error( self.name + ": EOF exception found" )
3289 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003290 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003291 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003292 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003293 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003294
kelvin-onlabd3b64892015-01-20 13:26:24 -08003295 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003296 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003297 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003298 deviceId must be the id of a device as seen in the onos devices command
3299 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003300 role must be either master, standby, or none
3301
Jon Halle3f39ff2015-01-13 11:50:53 -08003302 Returns:
3303 main.TRUE or main.FALSE based on argument verification and
3304 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003305 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003306 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003307 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003308 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003309 cmdStr = "device-role " +\
3310 str( deviceId ) + " " +\
3311 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003312 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003313 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003314 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003315 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003316 if re.search( "Error", handle ):
3317 # end color output to escape any colours
3318 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003319 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003320 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003321 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003322 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003323 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003324 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003325 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003326 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003327 except AssertionError:
3328 main.log.exception( "" )
3329 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003330 except TypeError:
3331 main.log.exception( self.name + ": Object not as expected" )
3332 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003333 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003334 main.log.error( self.name + ": EOF exception found" )
3335 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003336 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003337 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003338 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003339 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003340
kelvin-onlabd3b64892015-01-20 13:26:24 -08003341 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003342 """
Jon Hall0dd09952018-04-19 09:59:11 -07003343 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003344 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003345 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003346 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003347 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003348 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003349 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003350 cmdStr += " -j"
3351 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003352 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003353 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003354 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003355 except AssertionError:
3356 main.log.exception( "" )
3357 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003358 except TypeError:
3359 main.log.exception( self.name + ": Object not as expected" )
3360 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003361 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003362 main.log.error( self.name + ": EOF exception found" )
3363 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003364 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003365 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003366 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003367 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003368
kelvin-onlabd3b64892015-01-20 13:26:24 -08003369 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003370 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003371 CLI command to get the current leader for the Election test application
3372 NOTE: Requires installation of the onos-app-election feature
3373 Returns: Node IP of the leader if one exists
3374 None if none exists
3375 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003376 """
Jon Hall94fd0472014-12-08 11:52:42 -08003377 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003378 cmdStr = "election-test-leader"
3379 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003380 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003381 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003382 # Leader
3383 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003384 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003385 nodeSearch = re.search( leaderPattern, response )
3386 if nodeSearch:
3387 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003388 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003389 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003390 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003391 # no leader
3392 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003393 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003394 nullSearch = re.search( nullPattern, response )
3395 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003396 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003397 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003398 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003399 # error
Jon Hall0e240372018-05-02 11:21:57 -07003400 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003401 ": " + "unexpected response" )
3402 main.log.error( repr( response ) )
3403 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003404 except AssertionError:
3405 main.log.exception( "" )
3406 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003407 except TypeError:
3408 main.log.exception( self.name + ": Object not as expected" )
3409 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003410 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003411 main.log.error( self.name + ": EOF exception found" )
3412 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003413 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003414 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003415 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003416 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003417
kelvin-onlabd3b64892015-01-20 13:26:24 -08003418 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003419 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003420 CLI command to run for leadership of the Election test application.
3421 NOTE: Requires installation of the onos-app-election feature
3422 Returns: Main.TRUE on success
3423 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003424 """
Jon Hall94fd0472014-12-08 11:52:42 -08003425 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003426 cmdStr = "election-test-run"
3427 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003428 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003429 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003430 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003431 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003432 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003433 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003434 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003435 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003436 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003437 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003438 # error
Jon Hall0e240372018-05-02 11:21:57 -07003439 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003440 ": " + "unexpected response" )
3441 main.log.error( repr( response ) )
3442 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003443 except AssertionError:
3444 main.log.exception( "" )
3445 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003446 except TypeError:
3447 main.log.exception( self.name + ": Object not as expected" )
3448 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003449 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003450 main.log.error( self.name + ": EOF exception found" )
3451 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003452 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003453 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003454 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003455 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003456
kelvin-onlabd3b64892015-01-20 13:26:24 -08003457 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003458 """
Jon Hall94fd0472014-12-08 11:52:42 -08003459 * CLI command to withdraw the local node from leadership election for
3460 * the Election test application.
3461 #NOTE: Requires installation of the onos-app-election feature
3462 Returns: Main.TRUE on success
3463 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003464 """
Jon Hall94fd0472014-12-08 11:52:42 -08003465 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003466 cmdStr = "election-test-withdraw"
3467 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003468 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003469 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003470 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003471 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003472 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003473 if re.search( successPattern, response ):
3474 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003475 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003476 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003477 # error
Jon Hall0e240372018-05-02 11:21:57 -07003478 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003479 self.name + ": " + "unexpected response" )
3480 main.log.error( repr( response ) )
3481 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003482 except AssertionError:
3483 main.log.exception( "" )
3484 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003485 except TypeError:
3486 main.log.exception( self.name + ": Object not as expected" )
3487 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003488 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003489 main.log.error( self.name + ": EOF exception found" )
3490 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003491 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003492 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003493 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003494 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003495
kelvin8ec71442015-01-15 16:57:00 -08003496 def getDevicePortsEnabledCount( self, dpid ):
3497 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003498 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003499 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003500 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003501 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003502 cmdStr = "onos:ports -e " + dpid + " | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003503 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003504 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003505 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003506 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003507 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003508 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003509 return output
Jon Hallc6793552016-01-19 14:18:37 -08003510 except AssertionError:
3511 main.log.exception( "" )
3512 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003513 except TypeError:
3514 main.log.exception( self.name + ": Object not as expected" )
3515 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003516 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003517 main.log.error( self.name + ": EOF exception found" )
3518 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003519 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003520 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003521 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003522 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003523
kelvin8ec71442015-01-15 16:57:00 -08003524 def getDeviceLinksActiveCount( self, dpid ):
3525 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003526 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003527 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003528 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003529 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003530 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003531 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003532 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003533 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003534 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003535 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003536 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003537 return output
Jon Hallc6793552016-01-19 14:18:37 -08003538 except AssertionError:
3539 main.log.exception( "" )
3540 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003541 except TypeError:
3542 main.log.exception( self.name + ": Object not as expected" )
3543 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003544 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003545 main.log.error( self.name + ": EOF exception found" )
3546 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003547 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003548 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003549 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003550 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003551
kelvin8ec71442015-01-15 16:57:00 -08003552 def getAllIntentIds( self ):
3553 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003554 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003555 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003556 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003557 cmdStr = "onos:intents | grep id="
3558 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003559 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003560 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003561 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003562 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003563 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003564 return output
Jon Hallc6793552016-01-19 14:18:37 -08003565 except AssertionError:
3566 main.log.exception( "" )
3567 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003568 except TypeError:
3569 main.log.exception( self.name + ": Object not as expected" )
3570 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003571 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003572 main.log.error( self.name + ": EOF exception found" )
3573 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003574 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003575 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003576 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003577 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003578
Jon Hall73509952015-02-24 16:42:56 -08003579 def intentSummary( self ):
3580 """
Jon Hallefbd9792015-03-05 16:11:36 -08003581 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003582 """
3583 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003584 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003585 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003586 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003587 states.append( intent.get( 'state', None ) )
3588 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003589 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003590 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003591 except ( TypeError, ValueError ):
3592 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003593 return None
3594 except pexpect.EOF:
3595 main.log.error( self.name + ": EOF exception found" )
3596 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003597 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003598 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003599 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003600 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003601
Jon Hall61282e32015-03-19 11:34:11 -07003602 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003603 """
3604 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003605 Optional argument:
3606 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003607 """
Jon Hall63604932015-02-26 17:09:50 -08003608 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003609 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003610 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003611 cmdStr += " -j"
3612 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003613 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003614 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003615 return output
Jon Hallc6793552016-01-19 14:18:37 -08003616 except AssertionError:
3617 main.log.exception( "" )
3618 return None
Jon Hall63604932015-02-26 17:09:50 -08003619 except TypeError:
3620 main.log.exception( self.name + ": Object not as expected" )
3621 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003622 except pexpect.EOF:
3623 main.log.error( self.name + ": EOF exception found" )
3624 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003625 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003626 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003627 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003628 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003629
acsmarsa4a4d1e2015-07-10 16:01:24 -07003630 def leaderCandidates( self, jsonFormat=True ):
3631 """
3632 Returns the output of the leaders -c command.
3633 Optional argument:
3634 * jsonFormat - boolean indicating if you want output in json
3635 """
3636 try:
3637 cmdStr = "onos:leaders -c"
3638 if jsonFormat:
3639 cmdStr += " -j"
3640 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003641 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003642 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003643 return output
Jon Hallc6793552016-01-19 14:18:37 -08003644 except AssertionError:
3645 main.log.exception( "" )
3646 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003647 except TypeError:
3648 main.log.exception( self.name + ": Object not as expected" )
3649 return None
3650 except pexpect.EOF:
3651 main.log.error( self.name + ": EOF exception found" )
3652 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003653 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003654 except Exception:
3655 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003656 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003657
Jon Hallc6793552016-01-19 14:18:37 -08003658 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003659 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003660 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003661 topic parameter and an empty list if the topic doesn't exist
3662 If no leader is elected leader in the returned list will be "none"
3663 Returns None if there is a type error processing the json object
3664 """
3665 try:
Jon Hall6e709752016-02-01 13:38:46 -08003666 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003667 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003668 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003669 assert "Command not found:" not in rawOutput, rawOutput
3670 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003671 results = []
3672 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003673 if dict[ "topic" ] == topic:
3674 leader = dict[ "leader" ]
3675 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003676 results.append( leader )
3677 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003678 return results
Jon Hallc6793552016-01-19 14:18:37 -08003679 except AssertionError:
3680 main.log.exception( "" )
3681 return None
3682 except ( TypeError, ValueError ):
3683 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003684 return None
3685 except pexpect.EOF:
3686 main.log.error( self.name + ": EOF exception found" )
3687 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003688 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003689 except Exception:
3690 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003691 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003692
Jon Hall61282e32015-03-19 11:34:11 -07003693 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003694 """
3695 Returns the output of the intent Pending map.
3696 """
Jon Hall63604932015-02-26 17:09:50 -08003697 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003698 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003699 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003700 cmdStr += " -j"
3701 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003702 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003703 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003704 return output
Jon Hallc6793552016-01-19 14:18:37 -08003705 except AssertionError:
3706 main.log.exception( "" )
3707 return None
Jon Hall63604932015-02-26 17:09:50 -08003708 except TypeError:
3709 main.log.exception( self.name + ": Object not as expected" )
3710 return None
3711 except pexpect.EOF:
3712 main.log.error( self.name + ": EOF exception found" )
3713 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003714 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003715 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003716 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003717 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003718
Jon Hall2c8959e2016-12-16 12:17:34 -08003719 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003720 """
3721 Returns the output of the raft partitions command for ONOS.
3722 """
Jon Hall61282e32015-03-19 11:34:11 -07003723 # Sample JSON
3724 # {
3725 # "leader": "tcp://10.128.30.11:7238",
3726 # "members": [
3727 # "tcp://10.128.30.11:7238",
3728 # "tcp://10.128.30.17:7238",
3729 # "tcp://10.128.30.13:7238",
3730 # ],
3731 # "name": "p1",
3732 # "term": 3
3733 # },
Jon Hall63604932015-02-26 17:09:50 -08003734 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003735 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003736 if candidates:
3737 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003738 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003739 cmdStr += " -j"
3740 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003741 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003742 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003743 return output
Jon Hallc6793552016-01-19 14:18:37 -08003744 except AssertionError:
3745 main.log.exception( "" )
3746 return None
Jon Hall63604932015-02-26 17:09:50 -08003747 except TypeError:
3748 main.log.exception( self.name + ": Object not as expected" )
3749 return None
3750 except pexpect.EOF:
3751 main.log.error( self.name + ": EOF exception found" )
3752 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003753 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003754 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003755 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003756 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003757
Jon Halle9f909e2016-09-23 10:43:12 -07003758 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003759 """
3760 Returns the output of the apps command for ONOS. This command lists
3761 information about installed ONOS applications
3762 """
3763 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003764 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003765 # "description":"ONOS OpenFlow protocol southbound providers",
3766 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003767 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003768 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003769 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003770 if summary:
3771 cmdStr += " -s"
3772 if active:
3773 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003774 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003775 cmdStr += " -j"
3776 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003777 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003778 assert "Command not found:" not in output, output
3779 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003780 return output
Jon Hallbe379602015-03-24 13:39:32 -07003781 # FIXME: look at specific exceptions/Errors
3782 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003783 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003784 return None
3785 except TypeError:
3786 main.log.exception( self.name + ": Object not as expected" )
3787 return None
3788 except pexpect.EOF:
3789 main.log.error( self.name + ": EOF exception found" )
3790 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003791 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003792 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003793 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003794 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003795
You Wangcdc51fe2018-08-12 17:14:56 -07003796 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003797 """
3798 Uses the onos:apps cli command to return the status of an application.
3799 Returns:
3800 "ACTIVE" - If app is installed and activated
3801 "INSTALLED" - If app is installed and deactivated
3802 "UNINSTALLED" - If app is not installed
3803 None - on error
3804 """
Jon Hall146f1522015-03-24 15:33:24 -07003805 try:
3806 if not isinstance( appName, types.StringType ):
3807 main.log.error( self.name + ".appStatus(): appName must be" +
3808 " a string" )
3809 return None
3810 output = self.apps( jsonFormat=True )
3811 appsJson = json.loads( output )
3812 state = None
3813 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003814 if appName == app.get( 'name' ):
3815 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003816 break
3817 if state == "ACTIVE" or state == "INSTALLED":
3818 return state
3819 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003820 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003821 return "UNINSTALLED"
3822 elif state:
3823 main.log.error( "Unexpected state from 'onos:apps': " +
3824 str( state ) )
3825 return state
Jon Hallc6793552016-01-19 14:18:37 -08003826 except ( TypeError, ValueError ):
3827 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003828 return None
3829 except pexpect.EOF:
3830 main.log.error( self.name + ": EOF exception found" )
3831 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003832 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003833 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003834 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003835 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003836
Jon Hallbe379602015-03-24 13:39:32 -07003837 def app( self, appName, option ):
3838 """
3839 Interacts with the app command for ONOS. This command manages
3840 application inventory.
3841 """
Jon Hallbe379602015-03-24 13:39:32 -07003842 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003843 # Validate argument types
3844 valid = True
3845 if not isinstance( appName, types.StringType ):
3846 main.log.error( self.name + ".app(): appName must be a " +
3847 "string" )
3848 valid = False
3849 if not isinstance( option, types.StringType ):
3850 main.log.error( self.name + ".app(): option must be a string" )
3851 valid = False
3852 if not valid:
3853 return main.FALSE
3854 # Validate Option
3855 option = option.lower()
3856 # NOTE: Install may become a valid option
3857 if option == "activate":
3858 pass
3859 elif option == "deactivate":
3860 pass
3861 elif option == "uninstall":
3862 pass
3863 else:
3864 # Invalid option
3865 main.log.error( "The ONOS app command argument only takes " +
3866 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003867 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003868 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003869 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003870 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003871 assert output is not None, "Error in sendline"
3872 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003873 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003874 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003875 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003876 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003877 elif "No such application" in output:
3878 main.log.error( "The application '" + appName +
3879 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003880 return main.FALSE
3881 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003882 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003883 str( output ) )
3884 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003885 elif "Unsupported command:" in output:
3886 main.log.error( "Incorrect command given to 'app': " +
3887 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003888 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003889 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003890 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003891 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003892 except AssertionError:
3893 main.log.exception( self.name + ": AssertionError exception found" )
3894 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003895 except TypeError:
3896 main.log.exception( self.name + ": Object not as expected" )
3897 return main.ERROR
3898 except pexpect.EOF:
3899 main.log.error( self.name + ": EOF exception found" )
3900 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003901 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003902 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003903 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003904 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003905
Jon Hallbd16b922015-03-26 17:53:15 -07003906 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003907 """
3908 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003909 appName is the hierarchical app name, not the feature name
3910 If check is True, method will check the status of the app after the
3911 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003912 Returns main.TRUE if the command was successfully sent
3913 main.FALSE if the cli responded with an error or given
3914 incorrect input
3915 """
3916 try:
3917 if not isinstance( appName, types.StringType ):
3918 main.log.error( self.name + ".activateApp(): appName must be" +
3919 " a string" )
3920 return main.FALSE
3921 status = self.appStatus( appName )
3922 if status == "INSTALLED":
3923 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003924 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003925 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003926 status = self.appStatus( appName )
3927 if status == "ACTIVE":
3928 return main.TRUE
3929 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003930 main.log.debug( "The state of application " +
3931 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003932 time.sleep( 1 )
3933 return main.FALSE
3934 else: # not 'check' or command didn't succeed
3935 return response
Jon Hall146f1522015-03-24 15:33:24 -07003936 elif status == "ACTIVE":
3937 return main.TRUE
3938 elif status == "UNINSTALLED":
3939 main.log.error( self.name + ": Tried to activate the " +
3940 "application '" + appName + "' which is not " +
3941 "installed." )
3942 else:
3943 main.log.error( "Unexpected return value from appStatus: " +
3944 str( status ) )
3945 return main.ERROR
3946 except TypeError:
3947 main.log.exception( self.name + ": Object not as expected" )
3948 return main.ERROR
3949 except pexpect.EOF:
3950 main.log.error( self.name + ": EOF exception found" )
3951 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003952 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003953 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003954 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003955 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003956
Jon Hallbd16b922015-03-26 17:53:15 -07003957 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003958 """
3959 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003960 appName is the hierarchical app name, not the feature name
3961 If check is True, method will check the status of the app after the
3962 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003963 Returns main.TRUE if the command was successfully sent
3964 main.FALSE if the cli responded with an error or given
3965 incorrect input
3966 """
3967 try:
3968 if not isinstance( appName, types.StringType ):
3969 main.log.error( self.name + ".deactivateApp(): appName must " +
3970 "be a string" )
3971 return main.FALSE
3972 status = self.appStatus( appName )
3973 if status == "INSTALLED":
3974 return main.TRUE
3975 elif status == "ACTIVE":
3976 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003977 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003978 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003979 status = self.appStatus( appName )
3980 if status == "INSTALLED":
3981 return main.TRUE
3982 else:
3983 time.sleep( 1 )
3984 return main.FALSE
3985 else: # not check or command didn't succeed
3986 return response
Jon Hall146f1522015-03-24 15:33:24 -07003987 elif status == "UNINSTALLED":
3988 main.log.warn( self.name + ": Tried to deactivate the " +
3989 "application '" + appName + "' which is not " +
3990 "installed." )
3991 return main.TRUE
3992 else:
3993 main.log.error( "Unexpected return value from appStatus: " +
3994 str( status ) )
3995 return main.ERROR
3996 except TypeError:
3997 main.log.exception( self.name + ": Object not as expected" )
3998 return main.ERROR
3999 except pexpect.EOF:
4000 main.log.error( self.name + ": EOF exception found" )
4001 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004002 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004003 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004004 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004005 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004006
Jon Hallbd16b922015-03-26 17:53:15 -07004007 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004008 """
4009 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004010 appName is the hierarchical app name, not the feature name
4011 If check is True, method will check the status of the app after the
4012 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004013 Returns main.TRUE if the command was successfully sent
4014 main.FALSE if the cli responded with an error or given
4015 incorrect input
4016 """
4017 # TODO: check with Thomas about the state machine for apps
4018 try:
4019 if not isinstance( appName, types.StringType ):
4020 main.log.error( self.name + ".uninstallApp(): appName must " +
4021 "be a string" )
4022 return main.FALSE
4023 status = self.appStatus( appName )
4024 if status == "INSTALLED":
4025 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004026 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004027 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004028 status = self.appStatus( appName )
4029 if status == "UNINSTALLED":
4030 return main.TRUE
4031 else:
4032 time.sleep( 1 )
4033 return main.FALSE
4034 else: # not check or command didn't succeed
4035 return response
Jon Hall146f1522015-03-24 15:33:24 -07004036 elif status == "ACTIVE":
4037 main.log.warn( self.name + ": Tried to uninstall the " +
4038 "application '" + appName + "' which is " +
4039 "currently active." )
4040 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004041 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004042 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004043 status = self.appStatus( appName )
4044 if status == "UNINSTALLED":
4045 return main.TRUE
4046 else:
4047 time.sleep( 1 )
4048 return main.FALSE
4049 else: # not check or command didn't succeed
4050 return response
Jon Hall146f1522015-03-24 15:33:24 -07004051 elif status == "UNINSTALLED":
4052 return main.TRUE
4053 else:
4054 main.log.error( "Unexpected return value from appStatus: " +
4055 str( status ) )
4056 return main.ERROR
4057 except TypeError:
4058 main.log.exception( self.name + ": Object not as expected" )
4059 return main.ERROR
4060 except pexpect.EOF:
4061 main.log.error( self.name + ": EOF exception found" )
4062 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004063 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004064 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004065 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004066 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004067
4068 def appIDs( self, jsonFormat=True ):
4069 """
4070 Show the mappings between app id and app names given by the 'app-ids'
4071 cli command
4072 """
4073 try:
4074 cmdStr = "app-ids"
4075 if jsonFormat:
4076 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004077 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004078 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004079 assert "Command not found:" not in output, output
4080 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004081 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004082 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004083 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004084 return None
4085 except TypeError:
4086 main.log.exception( self.name + ": Object not as expected" )
4087 return None
4088 except pexpect.EOF:
4089 main.log.error( self.name + ": EOF exception found" )
4090 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004091 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004092 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004093 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004094 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004095
4096 def appToIDCheck( self ):
4097 """
4098 This method will check that each application's ID listed in 'apps' is
4099 the same as the ID listed in 'app-ids'. The check will also check that
4100 there are no duplicate IDs issued. Note that an app ID should be
4101 a globaly unique numerical identifier for app/app-like features. Once
4102 an ID is registered, the ID is never freed up so that if an app is
4103 reinstalled it will have the same ID.
4104
4105 Returns: main.TRUE if the check passes and
4106 main.FALSE if the check fails or
4107 main.ERROR if there is some error in processing the test
4108 """
4109 try:
Jon Hall0e240372018-05-02 11:21:57 -07004110 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004111 rawJson = self.appIDs( jsonFormat=True )
4112 if rawJson:
4113 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004114 else:
Jon Hall0e240372018-05-02 11:21:57 -07004115 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4116 return main.FALSE
4117
4118 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004119 rawJson = self.apps( jsonFormat=True )
4120 if rawJson:
4121 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004122 else:
Jon Hallc6793552016-01-19 14:18:37 -08004123 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004124 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004125
Jon Hallbd16b922015-03-26 17:53:15 -07004126 result = main.TRUE
4127 for app in apps:
4128 appID = app.get( 'id' )
4129 if appID is None:
4130 main.log.error( "Error parsing app: " + str( app ) )
4131 result = main.FALSE
4132 appName = app.get( 'name' )
4133 if appName is None:
4134 main.log.error( "Error parsing app: " + str( app ) )
4135 result = main.FALSE
4136 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004137 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004138 if not current: # if ids doesn't have this id
4139 result = main.FALSE
4140 main.log.error( "'app-ids' does not have the ID for " +
4141 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004142 main.log.debug( "apps command returned: " + str( app ) +
4143 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004144 elif len( current ) > 1:
4145 # there is more than one app with this ID
4146 result = main.FALSE
4147 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004148 elif not current[ 0 ][ 'name' ] == appName:
4149 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004150 result = main.FALSE
4151 main.log.error( "'app-ids' has " + str( currentName ) +
4152 " registered under id:" + str( appID ) +
4153 " but 'apps' has " + str( appName ) )
4154 else:
4155 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004156
Jon Hallbd16b922015-03-26 17:53:15 -07004157 # now make sure that app-ids has no duplicates
4158 idsList = []
4159 namesList = []
4160 for item in ids:
4161 idsList.append( item[ 'id' ] )
4162 namesList.append( item[ 'name' ] )
4163 if len( idsList ) != len( set( idsList ) ) or\
4164 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004165 main.log.error( "'app-ids' has some duplicate entries: \n"
4166 + json.dumps( ids,
4167 sort_keys=True,
4168 indent=4,
4169 separators=( ',', ': ' ) ) )
4170 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004171 return result
Jon Hallc6793552016-01-19 14:18:37 -08004172 except ( TypeError, ValueError ):
4173 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004174 return main.ERROR
4175 except pexpect.EOF:
4176 main.log.error( self.name + ": EOF exception found" )
4177 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004178 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004179 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004180 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004181 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004182
Jon Hallfb760a02015-04-13 15:35:03 -07004183 def getCfg( self, component=None, propName=None, short=False,
4184 jsonFormat=True ):
4185 """
4186 Get configuration settings from onos cli
4187 Optional arguments:
4188 component - Optionally only list configurations for a specific
4189 component. If None, all components with configurations
4190 are displayed. Case Sensitive string.
4191 propName - If component is specified, propName option will show
4192 only this specific configuration from that component.
4193 Case Sensitive string.
4194 jsonFormat - Returns output as json. Note that this will override
4195 the short option
4196 short - Short, less verbose, version of configurations.
4197 This is overridden by the json option
4198 returns:
4199 Output from cli as a string or None on error
4200 """
4201 try:
4202 baseStr = "cfg"
4203 cmdStr = " get"
4204 componentStr = ""
4205 if component:
4206 componentStr += " " + component
4207 if propName:
4208 componentStr += " " + propName
4209 if jsonFormat:
4210 baseStr += " -j"
4211 elif short:
4212 baseStr += " -s"
4213 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004214 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004215 assert "Command not found:" not in output, output
4216 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004217 return output
4218 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004219 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004220 return None
4221 except TypeError:
4222 main.log.exception( self.name + ": Object not as expected" )
4223 return None
4224 except pexpect.EOF:
4225 main.log.error( self.name + ": EOF exception found" )
4226 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004227 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004228 except Exception:
4229 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004230 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004231
4232 def setCfg( self, component, propName, value=None, check=True ):
4233 """
4234 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004235 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004236 component - The case sensitive name of the component whose
4237 property is to be set
4238 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004239 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004240 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004241 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004242 check - Boolean, Check whether the option was successfully set this
4243 only applies when a value is given.
4244 returns:
4245 main.TRUE on success or main.FALSE on failure. If check is False,
4246 will return main.TRUE unless there is an error
4247 """
4248 try:
4249 baseStr = "cfg"
4250 cmdStr = " set " + str( component ) + " " + str( propName )
4251 if value is not None:
4252 cmdStr += " " + str( value )
4253 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004254 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004255 assert "Command not found:" not in output, output
4256 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004257 if value and check:
4258 results = self.getCfg( component=str( component ),
4259 propName=str( propName ),
4260 jsonFormat=True )
4261 # Check if current value is what we just set
4262 try:
4263 jsonOutput = json.loads( results )
4264 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004265 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004266 main.log.exception( "Error parsing cfg output" )
4267 main.log.error( "output:" + repr( results ) )
4268 return main.FALSE
4269 if current == str( value ):
4270 return main.TRUE
4271 return main.FALSE
4272 return main.TRUE
4273 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004274 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004275 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004276 except ( TypeError, ValueError ):
4277 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004278 return main.FALSE
4279 except pexpect.EOF:
4280 main.log.error( self.name + ": EOF exception found" )
4281 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004282 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004283 except Exception:
4284 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004285 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004286
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004287 def distPrimitivesSend( self, cmd ):
4288 """
4289 Function to handle sending cli commands for the distributed primitives test app
4290
4291 This command will catch some exceptions and retry the command on some
4292 specific store exceptions.
4293
4294 Required arguments:
4295 cmd - The command to send to the cli
4296 returns:
4297 string containing the cli output
4298 None on Error
4299 """
4300 try:
4301 output = self.sendline( cmd )
4302 try:
4303 assert output is not None, "Error in sendline"
4304 # TODO: Maybe make this less hardcoded
4305 # ConsistentMap Exceptions
4306 assert "org.onosproject.store.service" not in output
4307 # Node not leader
4308 assert "java.lang.IllegalStateException" not in output
4309 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004310 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004311 "command: " + str( output ) )
4312 retryTime = 30 # Conservative time, given by Madan
4313 main.log.info( "Waiting " + str( retryTime ) +
4314 "seconds before retrying." )
4315 time.sleep( retryTime ) # Due to change in mastership
4316 output = self.sendline( cmd )
4317 assert output is not None, "Error in sendline"
4318 assert "Command not found:" not in output, output
4319 assert "Error executing command" not in output, output
4320 main.log.info( self.name + ": " + output )
4321 return output
4322 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004323 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004324 return None
4325 except TypeError:
4326 main.log.exception( self.name + ": Object not as expected" )
4327 return None
4328 except pexpect.EOF:
4329 main.log.error( self.name + ": EOF exception found" )
4330 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004331 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004332 except Exception:
4333 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004334 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004335
Jon Hall390696c2015-05-05 17:13:41 -07004336 def setTestAdd( self, setName, values ):
4337 """
4338 CLI command to add elements to a distributed set.
4339 Arguments:
4340 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004341 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004342 Example usages:
4343 setTestAdd( "set1", "a b c" )
4344 setTestAdd( "set2", "1" )
4345 returns:
4346 main.TRUE on success OR
4347 main.FALSE if elements were already in the set OR
4348 main.ERROR on error
4349 """
4350 try:
4351 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004352 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004353 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4354 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004355 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004356 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004357 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004358 return main.FALSE
4359 else:
4360 main.log.error( self.name + ": setTestAdd did not" +
4361 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004362 main.log.debug( self.name + " actual: " + repr( output ) )
4363 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004364 except TypeError:
4365 main.log.exception( self.name + ": Object not as expected" )
4366 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004367 except Exception:
4368 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004369 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004370
4371 def setTestRemove( self, setName, values, clear=False, retain=False ):
4372 """
4373 CLI command to remove elements from a distributed set.
4374 Required arguments:
4375 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004376 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004377 Optional arguments:
4378 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004379 retain - Retain only the given values. (intersection of the
4380 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004381 returns:
4382 main.TRUE on success OR
4383 main.FALSE if the set was not changed OR
4384 main.ERROR on error
4385 """
4386 try:
4387 cmdStr = "set-test-remove "
4388 if clear:
4389 cmdStr += "-c " + str( setName )
4390 elif retain:
4391 cmdStr += "-r " + str( setName ) + " " + str( values )
4392 else:
4393 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004394 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004395 if clear:
4396 pattern = "Set " + str( setName ) + " cleared"
4397 if re.search( pattern, output ):
4398 return main.TRUE
4399 elif retain:
4400 positivePattern = str( setName ) + " was pruned to contain " +\
4401 "only elements of set \[(.*)\]"
4402 negativePattern = str( setName ) + " was not changed by " +\
4403 "retaining only elements of the set " +\
4404 "\[(.*)\]"
4405 if re.search( positivePattern, output ):
4406 return main.TRUE
4407 elif re.search( negativePattern, output ):
4408 return main.FALSE
4409 else:
4410 positivePattern = "\[(.*)\] was removed from the set " +\
4411 str( setName )
4412 if ( len( values.split() ) == 1 ):
4413 negativePattern = "\[(.*)\] was not in set " +\
4414 str( setName )
4415 else:
4416 negativePattern = "No element of \[(.*)\] was in set " +\
4417 str( setName )
4418 if re.search( positivePattern, output ):
4419 return main.TRUE
4420 elif re.search( negativePattern, output ):
4421 return main.FALSE
4422 main.log.error( self.name + ": setTestRemove did not" +
4423 " match expected output" )
4424 main.log.debug( self.name + " expected: " + pattern )
4425 main.log.debug( self.name + " actual: " + repr( output ) )
4426 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004427 except TypeError:
4428 main.log.exception( self.name + ": Object not as expected" )
4429 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004430 except Exception:
4431 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004432 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004433
4434 def setTestGet( self, setName, values="" ):
4435 """
4436 CLI command to get the elements in a distributed set.
4437 Required arguments:
4438 setName - The name of the set to remove from.
4439 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004440 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004441 returns:
4442 main.ERROR on error OR
4443 A list of elements in the set if no optional arguments are
4444 supplied OR
4445 A tuple containing the list then:
4446 main.FALSE if the given values are not in the set OR
4447 main.TRUE if the given values are in the set OR
4448 """
4449 try:
4450 values = str( values ).strip()
4451 setName = str( setName ).strip()
4452 length = len( values.split() )
4453 containsCheck = None
4454 # Patterns to match
4455 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004456 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004457 containsTrue = "Set " + setName + " contains the value " + values
4458 containsFalse = "Set " + setName + " did not contain the value " +\
4459 values
4460 containsAllTrue = "Set " + setName + " contains the the subset " +\
4461 setPattern
4462 containsAllFalse = "Set " + setName + " did not contain the the" +\
4463 " subset " + setPattern
4464
4465 cmdStr = "set-test-get "
4466 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004467 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004468 if length == 0:
4469 match = re.search( pattern, output )
4470 else: # if given values
4471 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004472 patternTrue = pattern + "\r\n" + containsTrue
4473 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004474 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004475 patternTrue = pattern + "\r\n" + containsAllTrue
4476 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004477 matchTrue = re.search( patternTrue, output )
4478 matchFalse = re.search( patternFalse, output )
4479 if matchTrue:
4480 containsCheck = main.TRUE
4481 match = matchTrue
4482 elif matchFalse:
4483 containsCheck = main.FALSE
4484 match = matchFalse
4485 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004486 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004487 "expected output" )
4488 main.log.debug( self.name + " expected: " + pattern )
4489 main.log.debug( self.name + " actual: " + repr( output ) )
4490 match = None
4491 if match:
4492 setMatch = match.group( 1 )
4493 if setMatch == '':
4494 setList = []
4495 else:
4496 setList = setMatch.split( ", " )
4497 if length > 0:
4498 return ( setList, containsCheck )
4499 else:
4500 return setList
4501 else: # no match
4502 main.log.error( self.name + ": setTestGet did not" +
4503 " match expected output" )
4504 main.log.debug( self.name + " expected: " + pattern )
4505 main.log.debug( self.name + " actual: " + repr( output ) )
4506 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004507 except TypeError:
4508 main.log.exception( self.name + ": Object not as expected" )
4509 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004510 except Exception:
4511 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004512 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004513
4514 def setTestSize( self, setName ):
4515 """
4516 CLI command to get the elements in a distributed set.
4517 Required arguments:
4518 setName - The name of the set to remove from.
4519 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004520 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004521 None on error
4522 """
4523 try:
4524 # TODO: Should this check against the number of elements returned
4525 # and then return true/false based on that?
4526 setName = str( setName ).strip()
4527 # Patterns to match
4528 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004529 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004530 setPattern
4531 cmdStr = "set-test-get -s "
4532 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004533 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004534 if output:
4535 match = re.search( pattern, output )
4536 if match:
4537 setSize = int( match.group( 1 ) )
4538 setMatch = match.group( 2 )
4539 if len( setMatch.split() ) == setSize:
4540 main.log.info( "The size returned by " + self.name +
4541 " matches the number of elements in " +
4542 "the returned set" )
4543 else:
4544 main.log.error( "The size returned by " + self.name +
4545 " does not match the number of " +
4546 "elements in the returned set." )
4547 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004548 else: # no match
4549 main.log.error( self.name + ": setTestGet did not" +
4550 " match expected output" )
4551 main.log.debug( self.name + " expected: " + pattern )
4552 main.log.debug( self.name + " actual: " + repr( output ) )
4553 return None
Jon Hall390696c2015-05-05 17:13:41 -07004554 except TypeError:
4555 main.log.exception( self.name + ": Object not as expected" )
4556 return None
Jon Hall390696c2015-05-05 17:13:41 -07004557 except Exception:
4558 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004559 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004560
Jon Hall80daded2015-05-27 16:07:00 -07004561 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004562 """
4563 Command to list the various counters in the system.
4564 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004565 if jsonFormat, a string of the json object returned by the cli
4566 command
4567 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004568 None on error
4569 """
Jon Hall390696c2015-05-05 17:13:41 -07004570 try:
Jon Hall390696c2015-05-05 17:13:41 -07004571 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004572 if jsonFormat:
4573 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004574 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004575 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004576 assert "Command not found:" not in output, output
4577 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004578 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004579 return output
Jon Hall390696c2015-05-05 17:13:41 -07004580 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004581 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004582 return None
Jon Hall390696c2015-05-05 17:13:41 -07004583 except TypeError:
4584 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004585 return None
Jon Hall390696c2015-05-05 17:13:41 -07004586 except pexpect.EOF:
4587 main.log.error( self.name + ": EOF exception found" )
4588 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004589 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004590 except Exception:
4591 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004592 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004593
Jon Hall935db192016-04-19 00:22:04 -07004594 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004595 """
Jon Halle1a3b752015-07-22 13:02:46 -07004596 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004597 Required arguments:
4598 counter - The name of the counter to increment.
4599 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004600 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004601 returns:
4602 integer value of the counter or
4603 None on Error
4604 """
4605 try:
4606 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004607 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004608 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004609 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004610 if delta != 1:
4611 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004612 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004613 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004614 match = re.search( pattern, output )
4615 if match:
4616 return int( match.group( 1 ) )
4617 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004618 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004619 " match expected output." )
4620 main.log.debug( self.name + " expected: " + pattern )
4621 main.log.debug( self.name + " actual: " + repr( output ) )
4622 return None
Jon Hall390696c2015-05-05 17:13:41 -07004623 except TypeError:
4624 main.log.exception( self.name + ": Object not as expected" )
4625 return None
Jon Hall390696c2015-05-05 17:13:41 -07004626 except Exception:
4627 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004628 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004629
Jon Hall935db192016-04-19 00:22:04 -07004630 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004631 """
4632 CLI command to get a distributed counter then add a delta to it.
4633 Required arguments:
4634 counter - The name of the counter to increment.
4635 Optional arguments:
4636 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004637 returns:
4638 integer value of the counter or
4639 None on Error
4640 """
4641 try:
4642 counter = str( counter )
4643 delta = int( delta )
4644 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004645 cmdStr += counter
4646 if delta != 1:
4647 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004648 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004649 pattern = counter + " was updated to (-?\d+)"
4650 match = re.search( pattern, output )
4651 if match:
4652 return int( match.group( 1 ) )
4653 else:
4654 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4655 " match expected output." )
4656 main.log.debug( self.name + " expected: " + pattern )
4657 main.log.debug( self.name + " actual: " + repr( output ) )
4658 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004659 except TypeError:
4660 main.log.exception( self.name + ": Object not as expected" )
4661 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004662 except Exception:
4663 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004664 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004665
4666 def valueTestGet( self, valueName ):
4667 """
4668 CLI command to get the value of an atomic value.
4669 Required arguments:
4670 valueName - The name of the value to get.
4671 returns:
4672 string value of the value or
4673 None on Error
4674 """
4675 try:
4676 valueName = str( valueName )
4677 cmdStr = "value-test "
4678 operation = "get"
4679 cmdStr = "value-test {} {}".format( valueName,
4680 operation )
4681 output = self.distPrimitivesSend( cmdStr )
4682 pattern = "(\w+)"
4683 match = re.search( pattern, output )
4684 if match:
4685 return match.group( 1 )
4686 else:
4687 main.log.error( self.name + ": valueTestGet did not" +
4688 " match expected output." )
4689 main.log.debug( self.name + " expected: " + pattern )
4690 main.log.debug( self.name + " actual: " + repr( output ) )
4691 return None
4692 except TypeError:
4693 main.log.exception( self.name + ": Object not as expected" )
4694 return None
4695 except Exception:
4696 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004697 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004698
4699 def valueTestSet( self, valueName, newValue ):
4700 """
4701 CLI command to set the value of an atomic value.
4702 Required arguments:
4703 valueName - The name of the value to set.
4704 newValue - The value to assign to the given value.
4705 returns:
4706 main.TRUE on success or
4707 main.ERROR on Error
4708 """
4709 try:
4710 valueName = str( valueName )
4711 newValue = str( newValue )
4712 operation = "set"
4713 cmdStr = "value-test {} {} {}".format( valueName,
4714 operation,
4715 newValue )
4716 output = self.distPrimitivesSend( cmdStr )
4717 if output is not None:
4718 return main.TRUE
4719 else:
4720 return main.ERROR
4721 except TypeError:
4722 main.log.exception( self.name + ": Object not as expected" )
4723 return main.ERROR
4724 except Exception:
4725 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004726 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004727
4728 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4729 """
4730 CLI command to compareAndSet the value of an atomic value.
4731 Required arguments:
4732 valueName - The name of the value.
4733 oldValue - Compare the current value of the atomic value to this
4734 newValue - If the value equals oldValue, set the value to newValue
4735 returns:
4736 main.TRUE on success or
4737 main.FALSE on failure or
4738 main.ERROR on Error
4739 """
4740 try:
4741 valueName = str( valueName )
4742 oldValue = str( oldValue )
4743 newValue = str( newValue )
4744 operation = "compareAndSet"
4745 cmdStr = "value-test {} {} {} {}".format( valueName,
4746 operation,
4747 oldValue,
4748 newValue )
4749 output = self.distPrimitivesSend( cmdStr )
4750 pattern = "(\w+)"
4751 match = re.search( pattern, output )
4752 if match:
4753 result = match.group( 1 )
4754 if result == "true":
4755 return main.TRUE
4756 elif result == "false":
4757 return main.FALSE
4758 else:
4759 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4760 " match expected output." )
4761 main.log.debug( self.name + " expected: " + pattern )
4762 main.log.debug( self.name + " actual: " + repr( output ) )
4763 return main.ERROR
4764 except TypeError:
4765 main.log.exception( self.name + ": Object not as expected" )
4766 return main.ERROR
4767 except Exception:
4768 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004769 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004770
4771 def valueTestGetAndSet( self, valueName, newValue ):
4772 """
4773 CLI command to getAndSet the value of an atomic value.
4774 Required arguments:
4775 valueName - The name of the value to get.
4776 newValue - The value to assign to the given value
4777 returns:
4778 string value of the value or
4779 None on Error
4780 """
4781 try:
4782 valueName = str( valueName )
4783 cmdStr = "value-test "
4784 operation = "getAndSet"
4785 cmdStr += valueName + " " + operation
4786 cmdStr = "value-test {} {} {}".format( valueName,
4787 operation,
4788 newValue )
4789 output = self.distPrimitivesSend( cmdStr )
4790 pattern = "(\w+)"
4791 match = re.search( pattern, output )
4792 if match:
4793 return match.group( 1 )
4794 else:
4795 main.log.error( self.name + ": valueTestGetAndSet did not" +
4796 " match expected output." )
4797 main.log.debug( self.name + " expected: " + pattern )
4798 main.log.debug( self.name + " actual: " + repr( output ) )
4799 return None
4800 except TypeError:
4801 main.log.exception( self.name + ": Object not as expected" )
4802 return None
4803 except Exception:
4804 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004805 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004806
4807 def valueTestDestroy( self, valueName ):
4808 """
4809 CLI command to destroy an atomic value.
4810 Required arguments:
4811 valueName - The name of the value to destroy.
4812 returns:
4813 main.TRUE on success or
4814 main.ERROR on Error
4815 """
4816 try:
4817 valueName = str( valueName )
4818 cmdStr = "value-test "
4819 operation = "destroy"
4820 cmdStr += valueName + " " + operation
4821 output = self.distPrimitivesSend( cmdStr )
4822 if output is not None:
4823 return main.TRUE
4824 else:
4825 return main.ERROR
4826 except TypeError:
4827 main.log.exception( self.name + ": Object not as expected" )
4828 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004829 except Exception:
4830 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004831 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004832
YPZhangfebf7302016-05-24 16:45:56 -07004833 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004834 """
4835 Description: Execute summary command in onos
4836 Returns: json object ( summary -j ), returns main.FALSE if there is
4837 no output
4838
4839 """
4840 try:
4841 cmdStr = "summary"
4842 if jsonFormat:
4843 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004844 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004845 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004846 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004847 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004848 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004849 if not handle:
4850 main.log.error( self.name + ": There is no output in " +
4851 "summary command" )
4852 return main.FALSE
4853 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004854 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004855 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004856 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004857 except TypeError:
4858 main.log.exception( self.name + ": Object not as expected" )
4859 return None
4860 except pexpect.EOF:
4861 main.log.error( self.name + ": EOF exception found" )
4862 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004863 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004864 except Exception:
4865 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004866 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004867
Jon Hall935db192016-04-19 00:22:04 -07004868 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004869 """
4870 CLI command to get the value of a key in a consistent map using
4871 transactions. This a test function and can only get keys from the
4872 test map hard coded into the cli command
4873 Required arguments:
4874 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004875 returns:
4876 The string value of the key or
4877 None on Error
4878 """
4879 try:
4880 keyName = str( keyName )
4881 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004882 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004883 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004884 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4885 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004886 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004887 return None
4888 else:
4889 match = re.search( pattern, output )
4890 if match:
4891 return match.groupdict()[ 'value' ]
4892 else:
4893 main.log.error( self.name + ": transactionlMapGet did not" +
4894 " match expected output." )
4895 main.log.debug( self.name + " expected: " + pattern )
4896 main.log.debug( self.name + " actual: " + repr( output ) )
4897 return None
4898 except TypeError:
4899 main.log.exception( self.name + ": Object not as expected" )
4900 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004901 except Exception:
4902 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004903 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004904
Jon Hall935db192016-04-19 00:22:04 -07004905 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004906 """
4907 CLI command to put a value into 'numKeys' number of keys in a
4908 consistent map using transactions. This a test function and can only
4909 put into keys named 'Key#' of the test map hard coded into the cli command
4910 Required arguments:
4911 numKeys - Number of keys to add the value to
4912 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004913 returns:
4914 A dictionary whose keys are the name of the keys put into the map
4915 and the values of the keys are dictionaries whose key-values are
4916 'value': value put into map and optionaly
4917 'oldValue': Previous value in the key or
4918 None on Error
4919
4920 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004921 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4922 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004923 """
4924 try:
4925 numKeys = str( numKeys )
4926 value = str( value )
4927 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004928 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004929 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004930 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4931 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4932 results = {}
4933 for line in output.splitlines():
4934 new = re.search( newPattern, line )
4935 updated = re.search( updatedPattern, line )
4936 if new:
4937 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4938 elif updated:
4939 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004940 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004941 else:
4942 main.log.error( self.name + ": transactionlMapGet did not" +
4943 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004944 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4945 newPattern,
4946 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004947 main.log.debug( self.name + " actual: " + repr( output ) )
4948 return results
Jon Hall0e240372018-05-02 11:21:57 -07004949 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004950 main.log.exception( self.name + ": Object not as expected" )
4951 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004952 except Exception:
4953 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004954 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004955
acsmarsdaea66c2015-09-03 11:44:06 -07004956 def maps( self, jsonFormat=True ):
4957 """
4958 Description: Returns result of onos:maps
4959 Optional:
4960 * jsonFormat: enable json formatting of output
4961 """
4962 try:
4963 cmdStr = "maps"
4964 if jsonFormat:
4965 cmdStr += " -j"
4966 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004967 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004968 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004969 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004970 except AssertionError:
4971 main.log.exception( "" )
4972 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004973 except TypeError:
4974 main.log.exception( self.name + ": Object not as expected" )
4975 return None
4976 except pexpect.EOF:
4977 main.log.error( self.name + ": EOF exception found" )
4978 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004979 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004980 except Exception:
4981 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004982 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004983
4984 def getSwController( self, uri, jsonFormat=True ):
4985 """
4986 Descrition: Gets the controller information from the device
4987 """
4988 try:
4989 cmd = "device-controllers "
4990 if jsonFormat:
4991 cmd += "-j "
4992 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004993 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004994 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004995 return response
Jon Hallc6793552016-01-19 14:18:37 -08004996 except AssertionError:
4997 main.log.exception( "" )
4998 return None
GlennRC050596c2015-11-18 17:06:41 -08004999 except TypeError:
5000 main.log.exception( self.name + ": Object not as expected" )
5001 return None
5002 except pexpect.EOF:
5003 main.log.error( self.name + ": EOF exception found" )
5004 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005005 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005006 except Exception:
5007 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005008 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005009
5010 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
5011 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005012 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08005013
5014 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005015 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08005016 ip - String or List: The ip address of the controller.
5017 This parameter can be formed in a couple of different ways.
5018 VALID:
5019 10.0.0.1 - just the ip address
5020 tcp:10.0.0.1 - the protocol and the ip address
5021 tcp:10.0.0.1:6653 - the protocol and port can be specified,
5022 so that you can add controllers with different
5023 protocols and ports
5024 INVALID:
5025 10.0.0.1:6653 - this is not supported by ONOS
5026
5027 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
5028 port - The port number.
5029 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
5030
5031 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
5032 """
5033 try:
5034 cmd = "device-setcontrollers"
5035
5036 if jsonFormat:
5037 cmd += " -j"
5038 cmd += " " + uri
5039 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005040 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08005041 for item in ip:
5042 if ":" in item:
5043 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005044 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08005045 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005046 elif "." in sitem[ 1 ]:
5047 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08005048 else:
5049 main.log.error( "Malformed entry: " + item )
5050 raise TypeError
5051 else:
5052 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08005053 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07005054 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005055 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005056 if "Error" in response:
5057 main.log.error( response )
5058 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005059 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005060 except AssertionError:
5061 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005062 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005063 except TypeError:
5064 main.log.exception( self.name + ": Object not as expected" )
5065 return main.FALSE
5066 except pexpect.EOF:
5067 main.log.error( self.name + ": EOF exception found" )
5068 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005069 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005070 except Exception:
5071 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005072 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005073
5074 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005075 '''
GlennRC20fc6522015-12-23 23:26:57 -08005076 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005077 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005078 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005079 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005080 Returns:
5081 Returns main.FALSE if an exception is thrown or an error is present
5082 in the response. Otherwise, returns main.TRUE.
5083 NOTE:
5084 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005085 '''
GlennRC20fc6522015-12-23 23:26:57 -08005086 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005087 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005088 deviceStr = device
5089 device = []
5090 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005091
5092 for d in device:
5093 time.sleep( 1 )
5094 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005095 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005096 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005097 if "Error" in response:
5098 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5099 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005100 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005101 except AssertionError:
5102 main.log.exception( "" )
5103 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005104 except TypeError:
5105 main.log.exception( self.name + ": Object not as expected" )
5106 return main.FALSE
5107 except pexpect.EOF:
5108 main.log.error( self.name + ": EOF exception found" )
5109 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005110 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005111 except Exception:
5112 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005113 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005114
5115 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005116 '''
GlennRC20fc6522015-12-23 23:26:57 -08005117 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005118 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005119 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005120 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005121 Returns:
5122 Returns main.FALSE if an exception is thrown or an error is present
5123 in the response. Otherwise, returns main.TRUE.
5124 NOTE:
5125 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005126 '''
GlennRC20fc6522015-12-23 23:26:57 -08005127 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005128 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005129 host = list( host )
5130
5131 for h in host:
5132 time.sleep( 1 )
5133 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005134 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005135 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005136 if "Error" in response:
5137 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5138 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005139 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005140 except AssertionError:
5141 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005142 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005143 except TypeError:
5144 main.log.exception( self.name + ": Object not as expected" )
5145 return main.FALSE
5146 except pexpect.EOF:
5147 main.log.error( self.name + ": EOF exception found" )
5148 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005149 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005150 except Exception:
5151 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005152 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005153
YPZhangfebf7302016-05-24 16:45:56 -07005154 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005155 '''
GlennRCed771242016-01-13 17:02:47 -08005156 Description:
5157 Bring link down or up in the null-provider.
5158 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005159 begin - (string) One end of a device or switch.
5160 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005161 returns:
5162 main.TRUE if no exceptions were thrown and no Errors are
5163 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005164 '''
GlennRCed771242016-01-13 17:02:47 -08005165 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005166 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005167 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005168 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005169 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005170 if "Error" in response or "Failure" in response:
5171 main.log.error( response )
5172 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005173 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005174 except AssertionError:
5175 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005176 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005177 except TypeError:
5178 main.log.exception( self.name + ": Object not as expected" )
5179 return main.FALSE
5180 except pexpect.EOF:
5181 main.log.error( self.name + ": EOF exception found" )
5182 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005183 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005184 except Exception:
5185 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005186 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005187
Jon Hall2c8959e2016-12-16 12:17:34 -08005188 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005189 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005190 Description:
5191 Changes the state of port in an OF switch by means of the
5192 PORTSTATUS OF messages.
5193 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005194 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5195 port - (string) target port in the device. Ex: '2'
5196 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005197 returns:
5198 main.TRUE if no exceptions were thrown and no Errors are
5199 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005200 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005201 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005202 state = state.lower()
5203 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005204 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005205 response = self.sendline( cmd, showResponse=True )
5206 assert response is not None, "Error in sendline"
5207 assert "Command not found:" not in response, response
5208 if "Error" in response or "Failure" in response:
5209 main.log.error( response )
5210 return main.FALSE
5211 return main.TRUE
5212 except AssertionError:
5213 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005214 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005215 except TypeError:
5216 main.log.exception( self.name + ": Object not as expected" )
5217 return main.FALSE
5218 except pexpect.EOF:
5219 main.log.error( self.name + ": EOF exception found" )
5220 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005221 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005222 except Exception:
5223 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005224 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005225
5226 def logSet( self, level="INFO", app="org.onosproject" ):
5227 """
5228 Set the logging level to lvl for a specific app
5229 returns main.TRUE on success
5230 returns main.FALSE if Error occurred
5231 if noExit is True, TestON will not exit, but clean up
5232 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5233 Level defaults to INFO
5234 """
5235 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005236 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -08005237 self.handle.expect( self.karafPrompt )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005238
5239 response = self.handle.before
5240 if re.search( "Error", response ):
5241 return main.FALSE
5242 return main.TRUE
5243 except pexpect.TIMEOUT:
5244 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005245 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005246 except pexpect.EOF:
5247 main.log.error( self.name + ": EOF exception found" )
5248 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005249 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005250 except Exception:
5251 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005252 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005253
5254 def getGraphDict( self, timeout=60, includeHost=False ):
5255 """
5256 Return a dictionary which describes the latest network topology data as a
5257 graph.
5258 An example of the dictionary:
5259 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5260 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5261 Each vertex should at least have an 'edges' attribute which describes the
5262 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005263 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005264 list of attributes.
5265 An example of the edges dictionary:
5266 'edges': { vertex2: { 'port': ..., 'weight': ... },
5267 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005268 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005269 in topology data.
5270 """
5271 graphDict = {}
5272 try:
5273 links = self.links()
5274 links = json.loads( links )
5275 devices = self.devices()
5276 devices = json.loads( devices )
5277 idToDevice = {}
5278 for device in devices:
5279 idToDevice[ device[ 'id' ] ] = device
5280 if includeHost:
5281 hosts = self.hosts()
5282 # FIXME: support 'includeHost' argument
5283 for link in links:
5284 nodeA = link[ 'src' ][ 'device' ]
5285 nodeB = link[ 'dst' ][ 'device' ]
5286 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005287 if nodeA not in graphDict.keys():
5288 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005289 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005290 'type': idToDevice[ nodeA ][ 'type' ],
5291 'available': idToDevice[ nodeA ][ 'available' ],
5292 'role': idToDevice[ nodeA ][ 'role' ],
5293 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5294 'hw': idToDevice[ nodeA ][ 'hw' ],
5295 'sw': idToDevice[ nodeA ][ 'sw' ],
5296 'serial': idToDevice[ nodeA ][ 'serial' ],
5297 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005298 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005299 else:
5300 # Assert nodeB is not connected to any current links of nodeA
5301 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005302 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5303 'type': link[ 'type' ],
5304 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005305 return graphDict
5306 except ( TypeError, ValueError ):
5307 main.log.exception( self.name + ": Object not as expected" )
5308 return None
5309 except KeyError:
5310 main.log.exception( self.name + ": KeyError exception found" )
5311 return None
5312 except AssertionError:
5313 main.log.exception( self.name + ": AssertionError exception found" )
5314 return None
5315 except pexpect.EOF:
5316 main.log.error( self.name + ": EOF exception found" )
5317 main.log.error( self.name + ": " + self.handle.before )
5318 return None
5319 except Exception:
5320 main.log.exception( self.name + ": Uncaught exception!" )
5321 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005322
5323 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005324 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005325 Send command to check intent-perf summary
5326 Returns: dictionary for intent-perf summary
5327 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005328 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005329 cmd = "intent-perf -s"
5330 respDic = {}
5331 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005332 assert resp is not None, "Error in sendline"
5333 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005334 try:
5335 # Generate the dictionary to return
5336 for l in resp.split( "\n" ):
5337 # Delete any white space in line
5338 temp = re.sub( r'\s+', '', l )
5339 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005340 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005341
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005342 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005343 main.log.exception( self.name + ": Object not as expected" )
5344 return None
5345 except KeyError:
5346 main.log.exception( self.name + ": KeyError exception found" )
5347 return None
5348 except AssertionError:
5349 main.log.exception( self.name + ": AssertionError exception found" )
5350 return None
5351 except pexpect.EOF:
5352 main.log.error( self.name + ": EOF exception found" )
5353 main.log.error( self.name + ": " + self.handle.before )
5354 return None
5355 except Exception:
5356 main.log.exception( self.name + ": Uncaught exception!" )
5357 return None
5358 return respDic
5359
Chiyu Chengec63bde2016-11-17 18:11:36 -08005360 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005361 """
5362 Searches the latest ONOS log file for the given search term and
5363 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005364
chengchiyu08303a02016-09-08 17:40:26 -07005365 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005366 searchTerm:
5367 The string to grep from the ONOS log.
5368 startLine:
5369 The term that decides which line is the start to search the searchTerm in
5370 the karaf log. For now, startTerm only works in 'first' mode.
5371 logNum:
5372 In some extreme cases, one karaf log is not big enough to contain all the
5373 information.Because of this, search mutiply logs is necessary to capture
5374 the right result. logNum is the number of karaf logs that we need to search
5375 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005376 mode:
5377 all: return all the strings that contain the search term
5378 last: return the last string that contains the search term
5379 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005380 num: return the number of times that the searchTerm appears in the log
5381 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005382 """
5383 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005384 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005385 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005386 logPath = '/opt/onos/log/karaf.log.'
5387 logPaths = '/opt/onos/log/karaf.log'
5388 for i in range( 1, logNum ):
5389 logPaths = logPath + str( i ) + " " + logPaths
5390 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005391 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005392 # 100000000 is just a extreme large number to make sure this function can
5393 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005394 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005395 if mode == 'all':
5396 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005397 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005398 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005399 elif mode == 'first':
5400 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5401 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005402 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005403 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005404 return num
You Wang6d301d42017-04-21 10:49:33 -07005405 elif mode == 'total':
Jon Halld5a94fb2018-11-13 14:32:23 -08005406 totalLines = self.lineCount( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005407 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005408 else:
5409 main.log.error( self.name + " unsupported mode" )
5410 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005411 before = self.sendline( cmd )
5412 before = before.splitlines()
5413 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005414 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005415 return returnLines
5416 except AssertionError:
5417 main.log.error( self.name + " searchTerm is not string type" )
5418 return None
5419 except pexpect.EOF:
5420 main.log.error( self.name + ": EOF exception found" )
5421 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005422 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005423 except pexpect.TIMEOUT:
5424 main.log.error( self.name + ": TIMEOUT exception found" )
5425 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005426 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005427 except Exception:
5428 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005429 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005430
5431 def vplsShow( self, jsonFormat=True ):
5432 """
5433 Description: Returns result of onos:vpls show, which should list the
5434 configured VPLS networks and the assigned interfaces.
5435 Optional:
5436 * jsonFormat: enable json formatting of output
5437 Returns:
5438 The output of the command or None on error.
5439 """
5440 try:
5441 cmdStr = "vpls show"
5442 if jsonFormat:
5443 raise NotImplementedError
5444 cmdStr += " -j"
5445 handle = self.sendline( cmdStr )
5446 assert handle is not None, "Error in sendline"
5447 assert "Command not found:" not in handle, handle
5448 return handle
5449 except AssertionError:
5450 main.log.exception( "" )
5451 return None
5452 except TypeError:
5453 main.log.exception( self.name + ": Object not as expected" )
5454 return None
5455 except pexpect.EOF:
5456 main.log.error( self.name + ": EOF exception found" )
5457 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005458 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005459 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005460 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005461 return None
5462 except Exception:
5463 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005464 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005465
5466 def parseVplsShow( self ):
5467 """
5468 Parse the cli output of 'vpls show' into json output. This is required
5469 as there is currently no json output available.
5470 """
5471 try:
5472 output = []
5473 raw = self.vplsShow( jsonFormat=False )
5474 namePat = "VPLS name: (?P<name>\w+)"
5475 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5476 encapPat = "Encapsulation: (?P<encap>\w+)"
5477 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5478 mIter = re.finditer( pattern, raw )
5479 for match in mIter:
5480 item = {}
5481 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005482 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005483 if ifaces == [ "" ]:
5484 ifaces = []
5485 item[ 'interfaces' ] = ifaces
5486 encap = match.group( 'encap' )
5487 if encap != 'NONE':
5488 item[ 'encapsulation' ] = encap.lower()
5489 output.append( item )
5490 return output
5491 except Exception:
5492 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005493 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005494
5495 def vplsList( self, jsonFormat=True ):
5496 """
5497 Description: Returns result of onos:vpls list, which should list the
5498 configured VPLS networks.
5499 Optional:
5500 * jsonFormat: enable json formatting of output
5501 """
5502 try:
5503 cmdStr = "vpls list"
5504 if jsonFormat:
5505 raise NotImplementedError
5506 cmdStr += " -j"
5507 handle = self.sendline( cmdStr )
5508 assert handle is not None, "Error in sendline"
5509 assert "Command not found:" not in handle, handle
5510 return handle
5511 except AssertionError:
5512 main.log.exception( "" )
5513 return None
5514 except TypeError:
5515 main.log.exception( self.name + ": Object not as expected" )
5516 return None
5517 except pexpect.EOF:
5518 main.log.error( self.name + ": EOF exception found" )
5519 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005520 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005521 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005522 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005523 return None
5524 except Exception:
5525 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005526 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005527
5528 def vplsCreate( self, network ):
5529 """
5530 CLI command to create a new VPLS network.
5531 Required arguments:
5532 network - String name of the network to create.
5533 returns:
5534 main.TRUE on success and main.FALSE on failure
5535 """
5536 try:
5537 network = str( network )
5538 cmdStr = "vpls create "
5539 cmdStr += network
5540 output = self.sendline( cmdStr )
5541 assert output is not None, "Error in sendline"
5542 assert "Command not found:" not in output, output
5543 assert "Error executing command" not in output, output
5544 assert "VPLS already exists:" not in output, output
5545 return main.TRUE
5546 except AssertionError:
5547 main.log.exception( "" )
5548 return main.FALSE
5549 except TypeError:
5550 main.log.exception( self.name + ": Object not as expected" )
5551 return main.FALSE
5552 except pexpect.EOF:
5553 main.log.error( self.name + ": EOF exception found" )
5554 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005555 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005556 except Exception:
5557 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005558 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005559
5560 def vplsDelete( self, network ):
5561 """
5562 CLI command to delete a VPLS network.
5563 Required arguments:
5564 network - Name of the network to delete.
5565 returns:
5566 main.TRUE on success and main.FALSE on failure
5567 """
5568 try:
5569 network = str( network )
5570 cmdStr = "vpls delete "
5571 cmdStr += network
5572 output = self.sendline( cmdStr )
5573 assert output is not None, "Error in sendline"
5574 assert "Command not found:" not in output, output
5575 assert "Error executing command" not in output, output
5576 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005577 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005578 return main.TRUE
5579 except AssertionError:
5580 main.log.exception( "" )
5581 return main.FALSE
5582 except TypeError:
5583 main.log.exception( self.name + ": Object not as expected" )
5584 return main.FALSE
5585 except pexpect.EOF:
5586 main.log.error( self.name + ": EOF exception found" )
5587 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005588 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005589 except Exception:
5590 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005591 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005592
5593 def vplsAddIface( self, network, iface ):
5594 """
5595 CLI command to add an interface to a VPLS network.
5596 Required arguments:
5597 network - Name of the network to add the interface to.
5598 iface - The ONOS name for an interface.
5599 returns:
5600 main.TRUE on success and main.FALSE on failure
5601 """
5602 try:
5603 network = str( network )
5604 iface = str( iface )
5605 cmdStr = "vpls add-if "
5606 cmdStr += network + " " + iface
5607 output = self.sendline( cmdStr )
5608 assert output is not None, "Error in sendline"
5609 assert "Command not found:" not in output, output
5610 assert "Error executing command" not in output, output
5611 assert "already associated to network" not in output, output
5612 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005613 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005614 return main.TRUE
5615 except AssertionError:
5616 main.log.exception( "" )
5617 return main.FALSE
5618 except TypeError:
5619 main.log.exception( self.name + ": Object not as expected" )
5620 return main.FALSE
5621 except pexpect.EOF:
5622 main.log.error( self.name + ": EOF exception found" )
5623 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005624 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005625 except Exception:
5626 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005627 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005628
5629 def vplsRemIface( self, network, iface ):
5630 """
5631 CLI command to remove an interface from a VPLS network.
5632 Required arguments:
5633 network - Name of the network to remove the interface from.
5634 iface - Name of the interface to remove.
5635 returns:
5636 main.TRUE on success and main.FALSE on failure
5637 """
5638 try:
5639 iface = str( iface )
5640 cmdStr = "vpls rem-if "
5641 cmdStr += network + " " + iface
5642 output = self.sendline( cmdStr )
5643 assert output is not None, "Error in sendline"
5644 assert "Command not found:" not in output, output
5645 assert "Error executing command" not in output, output
5646 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005647 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005648 return main.TRUE
5649 except AssertionError:
5650 main.log.exception( "" )
5651 return main.FALSE
5652 except TypeError:
5653 main.log.exception( self.name + ": Object not as expected" )
5654 return main.FALSE
5655 except pexpect.EOF:
5656 main.log.error( self.name + ": EOF exception found" )
5657 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005658 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005659 except Exception:
5660 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005661 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005662
5663 def vplsClean( self ):
5664 """
5665 Description: Clears the VPLS app configuration.
5666 Returns: main.TRUE on success and main.FALSE on failure
5667 """
5668 try:
5669 cmdStr = "vpls clean"
5670 handle = self.sendline( cmdStr )
5671 assert handle is not None, "Error in sendline"
5672 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005673 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005674 return handle
5675 except AssertionError:
5676 main.log.exception( "" )
5677 return main.FALSE
5678 except TypeError:
5679 main.log.exception( self.name + ": Object not as expected" )
5680 return main.FALSE
5681 except pexpect.EOF:
5682 main.log.error( self.name + ": EOF exception found" )
5683 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005684 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005685 except Exception:
5686 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005687 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005688
5689 def vplsSetEncap( self, network, encapType ):
5690 """
5691 CLI command to add an interface to a VPLS network.
5692 Required arguments:
5693 network - Name of the network to create.
5694 encapType - Type of encapsulation.
5695 returns:
5696 main.TRUE on success and main.FALSE on failure
5697 """
5698 try:
5699 network = str( network )
5700 encapType = str( encapType ).upper()
5701 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5702 cmdStr = "vpls set-encap "
5703 cmdStr += network + " " + encapType
5704 output = self.sendline( cmdStr )
5705 assert output is not None, "Error in sendline"
5706 assert "Command not found:" not in output, output
5707 assert "Error executing command" not in output, output
5708 assert "already associated to network" not in output, output
5709 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005710 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005711 return main.TRUE
5712 except AssertionError:
5713 main.log.exception( "" )
5714 return main.FALSE
5715 except TypeError:
5716 main.log.exception( self.name + ": Object not as expected" )
5717 return main.FALSE
5718 except pexpect.EOF:
5719 main.log.error( self.name + ": EOF exception found" )
5720 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005721 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005722 except Exception:
5723 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005724 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005725
5726 def interfaces( self, jsonFormat=True ):
5727 """
5728 Description: Returns result of interfaces command.
5729 Optional:
5730 * jsonFormat: enable json formatting of output
5731 Returns:
5732 The output of the command or None on error.
5733 """
5734 try:
5735 cmdStr = "interfaces"
5736 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005737 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005738 cmdStr += " -j"
5739 handle = self.sendline( cmdStr )
5740 assert handle is not None, "Error in sendline"
5741 assert "Command not found:" not in handle, handle
5742 return handle
5743 except AssertionError:
5744 main.log.exception( "" )
5745 return None
5746 except TypeError:
5747 main.log.exception( self.name + ": Object not as expected" )
5748 return None
5749 except pexpect.EOF:
5750 main.log.error( self.name + ": EOF exception found" )
5751 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005752 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005753 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005754 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005755 return None
5756 except Exception:
5757 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005758 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005759
5760 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005761 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005762 Get the timestamp of searchTerm from karaf log.
5763
5764 Arguments:
5765 splitTerm_before and splitTerm_after:
5766
5767 The terms that split the string that contains the timeStamp of
5768 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5769 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5770 and the splitTerm_after is "x"
5771
5772 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005773 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005774 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005775 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005776 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005777 return main.ERROR
5778 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005779 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005780 main.log.warn( "Captured timestamp string is empty" )
5781 return main.ERROR
5782 lines = lines[ 0 ]
5783 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005784 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005785 # get the target value
5786 line = lines.split( splitTerm_before )
5787 key = line[ 1 ].split( splitTerm_after )
5788 return int( key[ 0 ] )
5789 except IndexError:
5790 main.log.warn( "Index Error!" )
5791 return main.ERROR
5792 except AssertionError:
5793 main.log.warn( "Search Term Not Found " )
5794 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005795
5796 def workQueueAdd( self, queueName, value ):
5797 """
5798 CLI command to add a string to the specified Work Queue.
5799 This function uses the distributed primitives test app, which
5800 gives some cli access to distributed primitives for testing
5801 purposes only.
5802
5803 Required arguments:
5804 queueName - The name of the queue to add to
5805 value - The value to add to the queue
5806 returns:
5807 main.TRUE on success, main.FALSE on failure and
5808 main.ERROR on error.
5809 """
5810 try:
5811 queueName = str( queueName )
5812 value = str( value )
5813 prefix = "work-queue-test"
5814 operation = "add"
5815 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5816 output = self.distPrimitivesSend( cmdStr )
5817 if "Invalid operation name" in output:
5818 main.log.warn( output )
5819 return main.ERROR
5820 elif "Done" in output:
5821 return main.TRUE
5822 except TypeError:
5823 main.log.exception( self.name + ": Object not as expected" )
5824 return main.ERROR
5825 except Exception:
5826 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005827 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005828
5829 def workQueueAddMultiple( self, queueName, value1, value2 ):
5830 """
5831 CLI command to add two strings to the specified Work Queue.
5832 This function uses the distributed primitives test app, which
5833 gives some cli access to distributed primitives for testing
5834 purposes only.
5835
5836 Required arguments:
5837 queueName - The name of the queue to add to
5838 value1 - The first value to add to the queue
5839 value2 - The second value to add to the queue
5840 returns:
5841 main.TRUE on success, main.FALSE on failure and
5842 main.ERROR on error.
5843 """
5844 try:
5845 queueName = str( queueName )
5846 value1 = str( value1 )
5847 value2 = str( value2 )
5848 prefix = "work-queue-test"
5849 operation = "addMultiple"
5850 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5851 output = self.distPrimitivesSend( cmdStr )
5852 if "Invalid operation name" in output:
5853 main.log.warn( output )
5854 return main.ERROR
5855 elif "Done" in output:
5856 return main.TRUE
5857 except TypeError:
5858 main.log.exception( self.name + ": Object not as expected" )
5859 return main.ERROR
5860 except Exception:
5861 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005862 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005863
5864 def workQueueTakeAndComplete( self, queueName, number=1 ):
5865 """
5866 CLI command to take a value from the specified Work Queue and compelte it.
5867 This function uses the distributed primitives test app, which
5868 gives some cli access to distributed primitives for testing
5869 purposes only.
5870
5871 Required arguments:
5872 queueName - The name of the queue to add to
5873 number - The number of items to take and complete
5874 returns:
5875 main.TRUE on success, main.FALSE on failure and
5876 main.ERROR on error.
5877 """
5878 try:
5879 queueName = str( queueName )
5880 number = str( int( number ) )
5881 prefix = "work-queue-test"
5882 operation = "takeAndComplete"
5883 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5884 output = self.distPrimitivesSend( cmdStr )
5885 if "Invalid operation name" in output:
5886 main.log.warn( output )
5887 return main.ERROR
5888 elif "Done" in output:
5889 return main.TRUE
5890 except TypeError:
5891 main.log.exception( self.name + ": Object not as expected" )
5892 return main.ERROR
5893 except Exception:
5894 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005895 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005896
5897 def workQueueDestroy( self, queueName ):
5898 """
5899 CLI command to destroy the specified Work Queue.
5900 This function uses the distributed primitives test app, which
5901 gives some cli access to distributed primitives for testing
5902 purposes only.
5903
5904 Required arguments:
5905 queueName - The name of the queue to add to
5906 returns:
5907 main.TRUE on success, main.FALSE on failure and
5908 main.ERROR on error.
5909 """
5910 try:
5911 queueName = str( queueName )
5912 prefix = "work-queue-test"
5913 operation = "destroy"
5914 cmdStr = " ".join( [ prefix, queueName, operation ] )
5915 output = self.distPrimitivesSend( cmdStr )
5916 if "Invalid operation name" in output:
5917 main.log.warn( output )
5918 return main.ERROR
5919 return main.TRUE
5920 except TypeError:
5921 main.log.exception( self.name + ": Object not as expected" )
5922 return main.ERROR
5923 except Exception:
5924 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005925 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005926
5927 def workQueueTotalPending( self, queueName ):
5928 """
5929 CLI command to get the Total Pending items of the specified Work Queue.
5930 This function uses the distributed primitives test app, which
5931 gives some cli access to distributed primitives for testing
5932 purposes only.
5933
5934 Required arguments:
5935 queueName - The name of the queue to add to
5936 returns:
5937 The number of Pending items in the specified work queue or
5938 None on error
5939 """
5940 try:
5941 queueName = str( queueName )
5942 prefix = "work-queue-test"
5943 operation = "totalPending"
5944 cmdStr = " ".join( [ prefix, queueName, operation ] )
5945 output = self.distPrimitivesSend( cmdStr )
5946 pattern = r'\d+'
5947 if "Invalid operation name" in output:
5948 main.log.warn( output )
5949 return None
5950 else:
5951 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005952 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005953 except ( AttributeError, TypeError ):
5954 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5955 return None
5956 except Exception:
5957 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005958 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005959
5960 def workQueueTotalCompleted( self, queueName ):
5961 """
5962 CLI command to get the Total Completed items of the specified Work Queue.
5963 This function uses the distributed primitives test app, which
5964 gives some cli access to distributed primitives for testing
5965 purposes only.
5966
5967 Required arguments:
5968 queueName - The name of the queue to add to
5969 returns:
5970 The number of complete items in the specified work queue or
5971 None on error
5972 """
5973 try:
5974 queueName = str( queueName )
5975 prefix = "work-queue-test"
5976 operation = "totalCompleted"
5977 cmdStr = " ".join( [ prefix, queueName, operation ] )
5978 output = self.distPrimitivesSend( cmdStr )
5979 pattern = r'\d+'
5980 if "Invalid operation name" in output:
5981 main.log.warn( output )
5982 return None
5983 else:
5984 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005985 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005986 except ( AttributeError, TypeError ):
5987 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5988 return None
5989 except Exception:
5990 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005991 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005992
5993 def workQueueTotalInProgress( self, queueName ):
5994 """
5995 CLI command to get the Total In Progress items of the specified Work Queue.
5996 This function uses the distributed primitives test app, which
5997 gives some cli access to distributed primitives for testing
5998 purposes only.
5999
6000 Required arguments:
6001 queueName - The name of the queue to add to
6002 returns:
6003 The number of In Progress items in the specified work queue or
6004 None on error
6005 """
6006 try:
6007 queueName = str( queueName )
6008 prefix = "work-queue-test"
6009 operation = "totalInProgress"
6010 cmdStr = " ".join( [ prefix, queueName, operation ] )
6011 output = self.distPrimitivesSend( cmdStr )
6012 pattern = r'\d+'
6013 if "Invalid operation name" in output:
6014 main.log.warn( output )
6015 return None
6016 else:
6017 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006018 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006019 except ( AttributeError, TypeError ):
6020 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6021 return None
6022 except Exception:
6023 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006024 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00006025
6026 def events( self, args='-a' ):
6027 """
6028 Description: Returns events -a command output
6029 Optional:
6030 add other arguments
6031 """
6032 try:
6033 cmdStr = "events"
6034 if args:
6035 cmdStr += " " + args
6036 handle = self.sendline( cmdStr )
6037 assert handle is not None, "Error in sendline"
6038 assert "Command not found:" not in handle, handle
6039 return handle
6040 except AssertionError:
6041 main.log.exception( "" )
6042 return None
6043 except TypeError:
6044 main.log.exception( self.name + ": Object not as expected" )
6045 return None
6046 except pexpect.EOF:
6047 main.log.error( self.name + ": EOF exception found" )
6048 main.log.error( self.name + ": " + self.handle.before )
6049 main.cleanAndExit()
6050 except Exception:
6051 main.log.exception( self.name + ": Uncaught exception!" )
6052 main.cleanAndExit()
6053
6054 def getMaster( self, deviceID ):
6055 """
6056 Description: Obtains current master using "roles" command for a specific deviceID
6057 """
6058 try:
6059 return str( self.getRole( deviceID )[ 'master' ] )
6060 except AssertionError:
6061 main.log.exception( "" )
6062 return None
6063 except TypeError:
6064 main.log.exception( self.name + ": Object not as expected" )
6065 return None
6066 except pexpect.EOF:
6067 main.log.error( self.name + ": EOF exception found" )
6068 main.log.error( self.name + ": " + self.handle.before )
6069 main.cleanAndExit()
6070 except Exception:
6071 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006072 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006073
6074 def issu( self ):
6075 """
6076 Short summary of In-Service Software Upgrade status
6077
6078 Returns the output of the cli command or None on Error
6079 """
6080 try:
6081 cmdStr = "issu"
6082 handle = self.sendline( cmdStr )
6083 assert handle is not None, "Error in sendline"
6084 assert "Command not found:" not in handle, handle
6085 assert "Unsupported command:" not in handle, handle
6086 return handle
6087 except AssertionError:
6088 main.log.exception( "" )
6089 return None
6090 except TypeError:
6091 main.log.exception( self.name + ": Object not as expected" )
6092 return None
6093 except pexpect.EOF:
6094 main.log.error( self.name + ": EOF exception found" )
6095 main.log.error( self.name + ": " + self.handle.before )
6096 main.cleanAndExit()
6097 except Exception:
6098 main.log.exception( self.name + ": Uncaught exception!" )
6099 main.cleanAndExit()
6100
6101 def issuInit( self ):
6102 """
6103 Initiates an In-Service Software Upgrade
6104
6105 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6106 """
6107 try:
6108 cmdStr = "issu init"
6109 handle = self.sendline( cmdStr )
6110 assert handle is not None, "Error in sendline"
6111 assert "Command not found:" not in handle, handle
6112 assert "Unsupported command:" not in handle, handle
6113 if "Initialized" in handle:
6114 return main.TRUE
6115 else:
6116 return main.FALSE
6117 except AssertionError:
6118 main.log.exception( "" )
6119 return main.ERROR
6120 except TypeError:
6121 main.log.exception( self.name + ": Object not as expected" )
6122 return main.ERROR
6123 except pexpect.EOF:
6124 main.log.error( self.name + ": EOF exception found" )
6125 main.log.error( self.name + ": " + self.handle.before )
6126 main.cleanAndExit()
6127 except Exception:
6128 main.log.exception( self.name + ": Uncaught exception!" )
6129 main.cleanAndExit()
6130
6131 def issuUpgrade( self ):
6132 """
6133 Transitions stores to upgraded nodes
6134
6135 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6136 """
6137 try:
6138 cmdStr = "issu upgrade"
6139 handle = self.sendline( cmdStr )
6140 assert handle is not None, "Error in sendline"
6141 assert "Command not found:" not in handle, handle
6142 assert "Unsupported command:" not in handle, handle
6143 if "Upgraded" in handle:
6144 return main.TRUE
6145 else:
6146 return main.FALSE
6147 except AssertionError:
6148 main.log.exception( "" )
6149 return main.ERROR
6150 except TypeError:
6151 main.log.exception( self.name + ": Object not as expected" )
6152 return main.ERROR
6153 except pexpect.EOF:
6154 main.log.error( self.name + ": EOF exception found" )
6155 main.log.error( self.name + ": " + self.handle.before )
6156 main.cleanAndExit()
6157 except Exception:
6158 main.log.exception( self.name + ": Uncaught exception!" )
6159 main.cleanAndExit()
6160
6161 def issuCommit( self ):
6162 """
6163 Finalizes an In-Service Software Upgrade
6164
6165 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6166 """
6167 try:
6168 cmdStr = "issu commit"
6169 handle = self.sendline( cmdStr )
6170 assert handle is not None, "Error in sendline"
6171 assert "Command not found:" not in handle, handle
6172 assert "Unsupported command:" not in handle, handle
6173 # TODO: Check the version returned by this command
6174 if "Committed version" in handle:
6175 return main.TRUE
6176 else:
6177 return main.FALSE
6178 except AssertionError:
6179 main.log.exception( "" )
6180 return main.ERROR
6181 except TypeError:
6182 main.log.exception( self.name + ": Object not as expected" )
6183 return main.ERROR
6184 except pexpect.EOF:
6185 main.log.error( self.name + ": EOF exception found" )
6186 main.log.error( self.name + ": " + self.handle.before )
6187 main.cleanAndExit()
6188 except Exception:
6189 main.log.exception( self.name + ": Uncaught exception!" )
6190 main.cleanAndExit()
6191
6192 def issuRollback( self ):
6193 """
6194 Rolls back an In-Service Software Upgrade
6195
6196 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6197 """
6198 try:
6199 cmdStr = "issu rollback"
6200 handle = self.sendline( cmdStr )
6201 assert handle is not None, "Error in sendline"
6202 assert "Command not found:" not in handle, handle
6203 assert "Unsupported command:" not in handle, handle
6204 # TODO: Check the version returned by this command
6205 if "Rolled back to version" in handle:
6206 return main.TRUE
6207 else:
6208 return main.FALSE
6209 except AssertionError:
6210 main.log.exception( "" )
6211 return main.ERROR
6212 except TypeError:
6213 main.log.exception( self.name + ": Object not as expected" )
6214 return main.ERROR
6215 except pexpect.EOF:
6216 main.log.error( self.name + ": EOF exception found" )
6217 main.log.error( self.name + ": " + self.handle.before )
6218 main.cleanAndExit()
6219 except Exception:
6220 main.log.exception( self.name + ": Uncaught exception!" )
6221 main.cleanAndExit()
6222
6223 def issuReset( self ):
6224 """
6225 Resets the In-Service Software Upgrade status after a rollback
6226
6227 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6228 """
6229 try:
6230 cmdStr = "issu reset"
6231 handle = self.sendline( cmdStr )
6232 assert handle is not None, "Error in sendline"
6233 assert "Command not found:" not in handle, handle
6234 assert "Unsupported command:" not in handle, handle
6235 # TODO: Check the version returned by this command
6236 if "Reset version" in handle:
6237 return main.TRUE
6238 else:
6239 return main.FALSE
6240 except AssertionError:
6241 main.log.exception( "" )
6242 return main.ERROR
6243 except TypeError:
6244 main.log.exception( self.name + ": Object not as expected" )
6245 return main.ERROR
6246 except pexpect.EOF:
6247 main.log.error( self.name + ": EOF exception found" )
6248 main.log.error( self.name + ": " + self.handle.before )
6249 main.cleanAndExit()
6250 except Exception:
6251 main.log.exception( self.name + ": Uncaught exception!" )
6252 main.cleanAndExit()
6253
6254 def issuStatus( self ):
6255 """
6256 Status of an In-Service Software Upgrade
6257
6258 Returns the output of the cli command or None on Error
6259 """
6260 try:
6261 cmdStr = "issu status"
6262 handle = self.sendline( cmdStr )
6263 assert handle is not None, "Error in sendline"
6264 assert "Command not found:" not in handle, handle
6265 assert "Unsupported command:" not in handle, handle
6266 return handle
6267 except AssertionError:
6268 main.log.exception( "" )
6269 return None
6270 except TypeError:
6271 main.log.exception( self.name + ": Object not as expected" )
6272 return None
6273 except pexpect.EOF:
6274 main.log.error( self.name + ": EOF exception found" )
6275 main.log.error( self.name + ": " + self.handle.before )
6276 main.cleanAndExit()
6277 except Exception:
6278 main.log.exception( self.name + ": Uncaught exception!" )
6279 main.cleanAndExit()
6280
6281 def issuVersion( self ):
6282 """
6283 Get the version of an In-Service Software Upgrade
6284
6285 Returns the output of the cli command or None on Error
6286 """
6287 try:
6288 cmdStr = "issu version"
6289 handle = self.sendline( cmdStr )
6290 assert handle is not None, "Error in sendline"
6291 assert "Command not found:" not in handle, handle
6292 assert "Unsupported command:" not in handle, handle
6293 return handle
6294 except AssertionError:
6295 main.log.exception( "" )
6296 return None
6297 except TypeError:
6298 main.log.exception( self.name + ": Object not as expected" )
6299 return None
6300 except pexpect.EOF:
6301 main.log.error( self.name + ": EOF exception found" )
6302 main.log.error( self.name + ": " + self.handle.before )
6303 main.cleanAndExit()
6304 except Exception:
6305 main.log.exception( self.name + ": Uncaught exception!" )
6306 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006307
6308 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6309 """
6310 Create a multicast route by calling 'mcast-join' command
6311 sIP: source IP of the multicast route
6312 groupIP: group IP of the multicast route
6313 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6314 dPorts: a list of destination ports of the multicast route
6315 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6316 """
6317 try:
6318 cmdStr = "mcast-join"
6319 cmdStr += " " + str( sIP )
6320 cmdStr += " " + str( groupIP )
6321 cmdStr += " " + str( sPort )
6322 assert isinstance( dPorts, list )
6323 for dPort in dPorts:
6324 cmdStr += " " + str( dPort )
6325 handle = self.sendline( cmdStr )
6326 assert handle is not None, "Error in sendline"
6327 assert "Command not found:" not in handle, handle
6328 assert "Unsupported command:" not in handle, handle
6329 assert "Error executing command" not in handle, handle
6330 if "Added the mcast route" in handle:
6331 return main.TRUE
6332 else:
6333 return main.FALSE
6334 except AssertionError:
6335 main.log.exception( "" )
6336 return None
6337 except TypeError:
6338 main.log.exception( self.name + ": Object not as expected" )
6339 return None
6340 except pexpect.EOF:
6341 main.log.error( self.name + ": EOF exception found" )
6342 main.log.error( self.name + ": " + self.handle.before )
6343 main.cleanAndExit()
6344 except Exception:
6345 main.log.exception( self.name + ": Uncaught exception!" )
6346 main.cleanAndExit()
6347
6348 def mcastDelete( self, sIP, groupIP, dPorts ):
6349 """
6350 Delete a multicast route by calling 'mcast-delete' command
6351 sIP: source IP of the multicast route
6352 groupIP: group IP of the multicast route
6353 dPorts: a list of destination ports of the multicast route
6354 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6355 """
6356 try:
6357 cmdStr = "mcast-delete"
6358 cmdStr += " " + str( sIP )
6359 cmdStr += " " + str( groupIP )
6360 assert isinstance( dPorts, list )
6361 for dPort in dPorts:
6362 cmdStr += " " + str( dPort )
6363 handle = self.sendline( cmdStr )
6364 assert handle is not None, "Error in sendline"
6365 assert "Command not found:" not in handle, handle
6366 assert "Unsupported command:" not in handle, handle
6367 assert "Error executing command" not in handle, handle
6368 if "Updated the mcast route" in handle:
6369 return main.TRUE
6370 else:
6371 return main.FALSE
6372 except AssertionError:
6373 main.log.exception( "" )
6374 return None
6375 except TypeError:
6376 main.log.exception( self.name + ": Object not as expected" )
6377 return None
6378 except pexpect.EOF:
6379 main.log.error( self.name + ": EOF exception found" )
6380 main.log.error( self.name + ": " + self.handle.before )
6381 main.cleanAndExit()
6382 except Exception:
6383 main.log.exception( self.name + ": Uncaught exception!" )
6384 main.cleanAndExit()
6385
6386 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6387 """
6388 Create a multicast route by calling 'mcast-host-join' command
6389 sAddr: we can provide * for ASM or a specific address for SSM
6390 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006391 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006392 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6393 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6394 """
6395 try:
6396 cmdStr = "mcast-host-join"
6397 cmdStr += " -sAddr " + str( sAddr )
6398 cmdStr += " -gAddr " + str( gAddr )
6399 assert isinstance( srcs, list )
6400 for src in srcs:
6401 cmdStr += " -srcs " + str( src )
6402 assert isinstance( sinks, list )
6403 for sink in sinks:
6404 cmdStr += " -sinks " + str( sink )
6405 handle = self.sendline( cmdStr )
6406 assert handle is not None, "Error in sendline"
6407 assert "Command not found:" not in handle, handle
6408 assert "Unsupported command:" not in handle, handle
6409 assert "Error executing command" not in handle, handle
6410 if "Added the mcast route" in handle:
6411 return main.TRUE
6412 else:
6413 return main.FALSE
6414 except AssertionError:
6415 main.log.exception( "" )
6416 return None
6417 except TypeError:
6418 main.log.exception( self.name + ": Object not as expected" )
6419 return None
6420 except pexpect.EOF:
6421 main.log.error( self.name + ": EOF exception found" )
6422 main.log.error( self.name + ": " + self.handle.before )
6423 main.cleanAndExit()
6424 except Exception:
6425 main.log.exception( self.name + ": Uncaught exception!" )
6426 main.cleanAndExit()
6427
6428 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6429 """
6430 Delete multicast sink(s) by calling 'mcast-host-delete' command
6431 sAddr: we can provide * for ASM or a specific address for SSM
6432 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006433 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006434 will delete the route if not specified
6435 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6436 """
6437 try:
6438 cmdStr = "mcast-host-delete"
6439 cmdStr += " -sAddr " + str( sAddr )
6440 cmdStr += " -gAddr " + str( gAddr )
6441 if host:
6442 cmdStr += " -h " + str( host )
6443 handle = self.sendline( cmdStr )
6444 assert handle is not None, "Error in sendline"
6445 assert "Command not found:" not in handle, handle
6446 assert "Unsupported command:" not in handle, handle
6447 assert "Error executing command" not in handle, handle
6448 if "Updated the mcast route" in handle:
6449 return main.TRUE
6450 elif "Deleted the mcast route" in handle:
6451 return main.TRUE
6452 else:
6453 return main.FALSE
6454 except AssertionError:
6455 main.log.exception( "" )
6456 return None
6457 except TypeError:
6458 main.log.exception( self.name + ": Object not as expected" )
6459 return None
6460 except pexpect.EOF:
6461 main.log.error( self.name + ": EOF exception found" )
6462 main.log.error( self.name + ": " + self.handle.before )
6463 main.cleanAndExit()
6464 except Exception:
6465 main.log.exception( self.name + ": Uncaught exception!" )
6466 main.cleanAndExit()
6467
You Wang547893e2018-05-08 13:34:59 -07006468 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6469 """
6470 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6471 sAddr: we can provide * for ASM or a specific address for SSM
6472 gAddr: specifies multicast group address
6473 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6474 will delete the route if not specified
6475 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6476 """
6477 try:
6478 cmdStr = "mcast-sink-delete"
6479 cmdStr += " -sAddr " + str( sAddr )
6480 cmdStr += " -gAddr " + str( gAddr )
6481 if sink:
6482 cmdStr += " -s " + str( sink )
6483 handle = self.sendline( cmdStr )
6484 assert handle is not None, "Error in sendline"
6485 assert "Command not found:" not in handle, handle
6486 assert "Unsupported command:" not in handle, handle
6487 assert "Error executing command" not in handle, handle
6488 if "Updated the mcast route" in handle:
6489 return main.TRUE
6490 elif "Deleted the mcast route" in handle:
6491 return main.TRUE
6492 else:
6493 return main.FALSE
6494 except AssertionError:
6495 main.log.exception( "" )
6496 return None
6497 except TypeError:
6498 main.log.exception( self.name + ": Object not as expected" )
6499 return None
6500 except pexpect.EOF:
6501 main.log.error( self.name + ": EOF exception found" )
6502 main.log.error( self.name + ": " + self.handle.before )
6503 main.cleanAndExit()
6504 except Exception:
6505 main.log.exception( self.name + ": Uncaught exception!" )
6506 main.cleanAndExit()
6507
You Wange24d6272018-03-27 21:18:50 -07006508 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6509 """
6510 Delete multicast src(s) by calling 'mcast-source-delete' command
6511 sAddr: we can provide * for ASM or a specific address for SSM
6512 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006513 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 -07006514 will delete the route if not specified
6515 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6516 """
6517 try:
6518 cmdStr = "mcast-source-delete"
6519 cmdStr += " -sAddr " + str( sAddr )
6520 cmdStr += " -gAddr " + str( gAddr )
6521 if srcs:
6522 assert isinstance( srcs, list )
6523 for src in srcs:
6524 cmdStr += " -src " + str( src )
6525 handle = self.sendline( cmdStr )
6526 assert handle is not None, "Error in sendline"
6527 assert "Command not found:" not in handle, handle
6528 assert "Unsupported command:" not in handle, handle
6529 assert "Error executing command" not in handle, handle
6530 if "Updated the mcast route" in handle:
6531 return main.TRUE
6532 elif "Deleted the mcast route" in handle:
6533 return main.TRUE
6534 else:
6535 return main.FALSE
6536 except AssertionError:
6537 main.log.exception( "" )
6538 return None
6539 except TypeError:
6540 main.log.exception( self.name + ": Object not as expected" )
6541 return None
6542 except pexpect.EOF:
6543 main.log.error( self.name + ": EOF exception found" )
6544 main.log.error( self.name + ": " + self.handle.before )
6545 main.cleanAndExit()
6546 except Exception:
6547 main.log.exception( self.name + ": Uncaught exception!" )
6548 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006549
6550 def netcfg( self, jsonFormat=True, args="" ):
6551 """
6552 Run netcfg cli command with given args
6553 """
6554 try:
6555 cmdStr = "netcfg"
6556 if jsonFormat:
6557 cmdStr = cmdStr + " -j"
6558 if args:
6559 cmdStr = cmdStr + " " + str( args )
6560 handle = self.sendline( cmdStr )
6561 assert handle is not None, "Error in sendline"
6562 assert "Command not found:" not in handle, handle
6563 assert "Unsupported command:" not in handle, handle
6564 assert "Error executing command" not in handle, handle
6565 return handle
6566 except AssertionError:
6567 main.log.exception( "" )
6568 return None
6569 except TypeError:
6570 main.log.exception( self.name + ": Object not as expected" )
6571 return None
6572 except pexpect.EOF:
6573 main.log.error( self.name + ": EOF exception found" )
6574 main.log.error( self.name + ": " + self.handle.before )
6575 main.cleanAndExit()
6576 except Exception:
6577 main.log.exception( self.name + ": Uncaught exception!" )
6578 main.cleanAndExit()
6579
You Wang0fa76e72018-05-18 11:33:25 -07006580 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006581 """
You Wang54b1d672018-06-11 16:44:13 -07006582 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006583 Options:
6584 sAddr: IP address of the source host
6585 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006586 ipv6: True if hosts are IPv6
6587 verbose: return verbose t3 output if True
6588 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006589 """
6590 try:
6591 # Collect information of both hosts from onos
6592 hosts = self.hosts()
6593 hosts = json.loads( hosts )
6594 sHost = None
6595 dHost = None
6596 for host in hosts:
6597 if sAddr in host[ "ipAddresses" ]:
6598 sHost = host
6599 elif dAddr in host[ "ipAddresses" ]:
6600 dHost = host
6601 if sHost and dHost:
6602 break
6603 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006604 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006605 if simple:
6606 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006607 cmdStr = "t3-troubleshoot-simple"
6608 if verbose:
6609 cmdStr += " -vv"
6610 if ipv6:
6611 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006612 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006613 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006614 else:
You Wang54b1d672018-06-11 16:44:13 -07006615 for location in sHost[ "locations" ]:
6616 cmdStr = "t3-troubleshoot"
6617 if verbose:
6618 cmdStr += " -vv"
6619 if ipv6:
6620 cmdStr += " -et ipv6"
6621 cmdStr += " -s " + str( sAddr )
6622 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6623 cmdStr += " -sm " + str( sHost[ "mac" ] )
6624 if sHost[ "vlan" ] != "None":
6625 cmdStr += " -vid " + sHost[ "vlan" ]
6626 cmdStr += " -d " + str( dAddr )
6627 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6628 netcfg = json.loads( netcfg )
6629 assert netcfg, "Failed to get netcfg"
6630 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6631 cmdList.append( cmdStr )
6632 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006633 except AssertionError:
6634 main.log.exception( "" )
6635 return None
6636 except ( KeyError, TypeError ):
6637 main.log.exception( self.name + ": Object not as expected" )
6638 return None
6639 except Exception:
6640 main.log.exception( self.name + ": Uncaught exception!" )
6641 main.cleanAndExit()
6642
6643 def t3( self, sAddr, dAddr, ipv6=False ):
6644 """
You Wang54b1d672018-06-11 16:44:13 -07006645 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006646 Options:
6647 sAddr: IP address of the source host
6648 dAddr: IP address of the destination host
6649 """
6650 try:
You Wang54b1d672018-06-11 16:44:13 -07006651 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6652 assert cmdList is not None, "composeT3Command returned None"
6653 t3Output = ""
6654 for cmdStr in cmdList:
6655 handle = self.sendline( cmdStr )
6656 assert handle is not None, "Error in sendline"
6657 assert "Command not found:" not in handle, handle
6658 assert "Unsupported command:" not in handle, handle
6659 assert "Error executing command" not in handle, handle
6660 assert "Tracing packet" in handle
6661 t3Output += handle
6662 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006663 except AssertionError:
6664 main.log.exception( "" )
6665 return None
6666 except pexpect.EOF:
6667 main.log.error( self.name + ": EOF exception found" )
6668 main.log.error( self.name + ": " + self.handle.before )
6669 main.cleanAndExit()
6670 except Exception:
6671 main.log.exception( self.name + ": Uncaught exception!" )
6672 main.cleanAndExit()