blob: 8d6a65bfd60970b5ab00928cf197ce07afa91a84 [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
Jon Hall39e3ffe2018-12-05 11:40:29 -0800561 karafEscape = re.compile( r"('(0|1)~\'|\r\r\r\n\x1b\[A\x1b\[79C(x)?|\x1b(>|=)|\x1b\[90m~)" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800562 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 Hallce0d70b2018-12-11 11:01:32 -0800594 cmdPattern = cmdStr.strip()
595 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
596 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800597 if relaxedRegex:
Jon Hallce0d70b2018-12-11 11:01:32 -0800598 cmdPattern = cmdPattern.split( '|' )[ -1 ].strip()
599 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
600 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800601 # This was added because karaf 4.2 is stripping some characters from the command echo
Jon Hallce0d70b2018-12-11 11:01:32 -0800602 output = response.split( cmdPattern, 1 )
Jon Hall39e3ffe2018-12-05 11:40:29 -0800603 if len( output ) < 2:
604 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800605 cmdPattern = cmdPattern[ -5: ]
606 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
607 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
608 output = response.split( cmdPattern, 1 )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800609 else:
Jon Hallce0d70b2018-12-11 11:01:32 -0800610 output = response.split( cmdPattern, 1 )
611 if len( output ) < 2: # TODO: Should we do this without the relaxedRegex flag?
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800612 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800613 output = response.split( cmdPattern[ -5: ], 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700614 if output:
615 if debug:
616 main.log.debug( self.name + ": split output" )
617 for r in output:
618 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallce0d70b2018-12-11 11:01:32 -0800619 if len( output ) == 1:
620 main.log.error( "Could not remove sent command echo from output" )
621 return output
Jon Hall0e240372018-05-02 11:21:57 -0700622 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800623 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800624 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700625 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800626 return output
GlennRCed771242016-01-13 17:02:47 -0800627 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700628 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800629 if debug:
630 main.log.debug( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700631 self.handle.send( "\x03" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800632 self.handle.expect( self.karafPrompt )
GlennRCed771242016-01-13 17:02:47 -0800633 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700634 except IndexError:
635 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700636 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700637 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800638 except TypeError:
639 main.log.exception( self.name + ": Object not as expected" )
640 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400641 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800642 main.log.error( self.name + ": EOF exception found" )
643 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700644 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700645 return None
646 else:
Devin Lim44075962017-08-11 10:56:37 -0700647 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800648 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800649 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700650 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700651 return None
652 else:
Devin Lim44075962017-08-11 10:56:37 -0700653 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400654
Jon Halld5a94fb2018-11-13 14:32:23 -0800655 def lineCount( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True ):
656 """
657 A wrapper around sendline(). Will return the number of lines returned or None on error
658
659 Required Arguments:
660 cmdStr - String to send to the pexpect session
661
662 Optional Arguments:
663 showResponse - Defaults to False. If True will log the response.
664 debug - Defaults to False. If True, will enable debug logging.
665 timeout - Defaults to 10. Amount of time in seconds for a command to return
666 before a timeout.
667 noExit - Defaults to False. If True, will not exit TestON in the event of a
668 closed channel, but instead return None
669 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.
670
671 Warning: There are no sanity checking to commands sent using this method.
672
673 """
674 try:
675 numLines = self.sendline( cmdStr, showResponse, debug, timeout, noExit, relaxedRegex )
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800676 parsed = re.search( "(\d+)\s+(\d+)", numLines )
677 if not parsed:
678 main.log.error( "Warning, output of karaf's wc may have changed" )
679 return None
680 return parsed.group( 1 )
Jon Halld5a94fb2018-11-13 14:32:23 -0800681 except IndexError:
682 main.log.exception( self.name + ": Object not as expected" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800683 main.log.debug( "response: {}".format( repr( numLines ) ) )
Jon Halld5a94fb2018-11-13 14:32:23 -0800684 return None
685 except TypeError:
686 main.log.exception( self.name + ": Object not as expected" )
687 return None
688 except Exception:
689 main.log.exception( self.name + ": Uncaught exception!" )
690 if noExit:
691 return None
692 else:
693 main.cleanAndExit()
694
kelvin8ec71442015-01-15 16:57:00 -0800695 # IMPORTANT NOTE:
696 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800697 # the cli command changing 'a:b' with 'aB'.
698 # Ex ) onos:topology > onosTopology
699 # onos:links > onosLinks
700 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800701
kelvin-onlabd3b64892015-01-20 13:26:24 -0800702 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800703 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400704 Adds a new cluster node by ID and address information.
705 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800706 * nodeId
707 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400708 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800709 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800710 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400711 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800712 cmdStr = "add-node " + str( nodeId ) + " " +\
713 str( ONOSIp ) + " " + str( tcpPort )
714 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700715 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800716 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800717 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700718 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800719 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800720 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400721 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800722 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400723 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800724 except AssertionError:
725 main.log.exception( "" )
726 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800727 except TypeError:
728 main.log.exception( self.name + ": Object not as expected" )
729 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400730 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800731 main.log.error( self.name + ": EOF exception found" )
732 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700733 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800734 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800735 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700736 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400737
kelvin-onlabd3b64892015-01-20 13:26:24 -0800738 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800739 """
andrewonlab86dc3082014-10-13 18:18:38 -0400740 Removes a cluster by ID
741 Issues command: 'remove-node [<node-id>]'
742 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800743 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800744 """
andrewonlab86dc3082014-10-13 18:18:38 -0400745 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400746
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700748 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700749 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800750 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700751 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700752 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700753 main.log.error( handle )
754 return main.FALSE
755 else:
756 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800757 except AssertionError:
758 main.log.exception( "" )
759 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800760 except TypeError:
761 main.log.exception( self.name + ": Object not as expected" )
762 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400763 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800764 main.log.error( self.name + ": EOF exception found" )
765 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700766 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800767 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800768 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700769 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400770
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700771 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800772 """
andrewonlab7c211572014-10-15 16:45:20 -0400773 List the nodes currently visible
774 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700775 Optional argument:
776 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800777 """
andrewonlab7c211572014-10-15 16:45:20 -0400778 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700779 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700780 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700781 cmdStr += " -j"
782 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700783 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800784 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700785 return output
Jon Hallc6793552016-01-19 14:18:37 -0800786 except AssertionError:
787 main.log.exception( "" )
788 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800789 except TypeError:
790 main.log.exception( self.name + ": Object not as expected" )
791 return None
andrewonlab7c211572014-10-15 16:45:20 -0400792 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800793 main.log.error( self.name + ": EOF exception found" )
794 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700795 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800796 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800797 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700798 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400799
kelvin8ec71442015-01-15 16:57:00 -0800800 def topology( self ):
801 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700802 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700803 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700804 Return:
805 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800806 """
andrewonlab95ce8322014-10-13 14:12:04 -0400807 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700808 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800809 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800810 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800811 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700812 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400813 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800814 except AssertionError:
815 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800816 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800817 except TypeError:
818 main.log.exception( self.name + ": Object not as expected" )
819 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400820 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800821 main.log.error( self.name + ": EOF exception found" )
822 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700823 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800824 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800825 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700826 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800827
jenkins7ead5a82015-03-13 10:28:21 -0700828 def deviceRemove( self, deviceId ):
829 """
830 Removes particular device from storage
831
832 TODO: refactor this function
833 """
834 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700835 cmdStr = "device-remove " + str( deviceId )
836 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800837 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800838 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700839 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700840 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700841 main.log.error( handle )
842 return main.FALSE
843 else:
844 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800845 except AssertionError:
846 main.log.exception( "" )
847 return None
jenkins7ead5a82015-03-13 10:28:21 -0700848 except TypeError:
849 main.log.exception( self.name + ": Object not as expected" )
850 return None
851 except pexpect.EOF:
852 main.log.error( self.name + ": EOF exception found" )
853 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700854 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700855 except Exception:
856 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700857 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700858
You Wang3b9689a2018-08-30 12:24:00 -0700859 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800860 """
Jon Hall7b02d952014-10-17 20:14:54 -0400861 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400862 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800863 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800864 """
andrewonlab86dc3082014-10-13 18:18:38 -0400865 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700866 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800867 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700868 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700869 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800870 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800871 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700872 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800873 except AssertionError:
874 main.log.exception( "" )
875 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800876 except TypeError:
877 main.log.exception( self.name + ": Object not as expected" )
878 return None
andrewonlab7c211572014-10-15 16:45:20 -0400879 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800880 main.log.error( self.name + ": EOF exception found" )
881 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700882 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800883 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800884 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700885 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400886
kelvin-onlabd3b64892015-01-20 13:26:24 -0800887 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800888 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800889 This balances the devices across all controllers
890 by issuing command: 'onos> onos:balance-masters'
891 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800892 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800893 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800894 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700895 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800896 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800897 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700898 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700899 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700900 main.log.error( handle )
901 return main.FALSE
902 else:
903 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800904 except AssertionError:
905 main.log.exception( "" )
906 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800907 except TypeError:
908 main.log.exception( self.name + ": Object not as expected" )
909 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800910 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800911 main.log.error( self.name + ": EOF exception found" )
912 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700913 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800914 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800915 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700916 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800917
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000918 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700919 """
920 Returns the output of the masters command.
921 Optional argument:
922 * jsonFormat - boolean indicating if you want output in json
923 """
924 try:
925 cmdStr = "onos:masters"
926 if jsonFormat:
927 cmdStr += " -j"
928 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700929 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800930 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700931 return output
Jon Hallc6793552016-01-19 14:18:37 -0800932 except AssertionError:
933 main.log.exception( "" )
934 return None
acsmars24950022015-07-30 18:00:43 -0700935 except TypeError:
936 main.log.exception( self.name + ": Object not as expected" )
937 return None
938 except pexpect.EOF:
939 main.log.error( self.name + ": EOF exception found" )
940 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700941 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700942 except Exception:
943 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700944 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700945
Jon Hallc6793552016-01-19 14:18:37 -0800946 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700947 """
948 Uses the master command to check that the devices' leadership
949 is evenly divided
950
951 Dependencies: checkMasters() and summary()
952
Jon Hall6509dbf2016-06-21 17:01:17 -0700953 Returns main.TRUE if the devices are balanced
954 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700955 Exits on Exception
956 Returns None on TypeError
957 """
958 try:
Jon Hallc6793552016-01-19 14:18:37 -0800959 summaryOutput = self.summary()
960 totalDevices = json.loads( summaryOutput )[ "devices" ]
961 except ( TypeError, ValueError ):
962 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
963 return None
964 try:
acsmars24950022015-07-30 18:00:43 -0700965 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800966 mastersOutput = self.checkMasters()
967 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700968 first = masters[ 0 ][ "size" ]
969 for master in masters:
970 totalOwnedDevices += master[ "size" ]
971 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
972 main.log.error( "Mastership not balanced" )
973 main.log.info( "\n" + self.checkMasters( False ) )
974 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700975 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700976 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700977 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800978 except ( TypeError, ValueError ):
979 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700980 return None
981 except pexpect.EOF:
982 main.log.error( self.name + ": EOF exception found" )
983 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700984 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700985 except Exception:
986 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700987 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700988
YPZhangfebf7302016-05-24 16:45:56 -0700989 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800990 """
Jon Halle8217482014-10-17 13:49:14 -0400991 Lists all core links
992 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800993 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800994 """
Jon Halle8217482014-10-17 13:49:14 -0400995 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700996 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800997 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700998 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700999 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001000 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001001 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001002 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001003 except AssertionError:
1004 main.log.exception( "" )
1005 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001006 except TypeError:
1007 main.log.exception( self.name + ": Object not as expected" )
1008 return None
Jon Halle8217482014-10-17 13:49:14 -04001009 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001010 main.log.error( self.name + ": EOF exception found" )
1011 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001012 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001013 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001014 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001015 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001016
You Wang3b9689a2018-08-30 12:24:00 -07001017 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001018 """
Jon Halle8217482014-10-17 13:49:14 -04001019 Lists all ports
1020 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001021 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001022 """
Jon Halle8217482014-10-17 13:49:14 -04001023 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001024 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001025 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001026 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -07001027 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001028 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001029 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001030 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001031 except AssertionError:
1032 main.log.exception( "" )
1033 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001034 except TypeError:
1035 main.log.exception( self.name + ": Object not as expected" )
1036 return None
Jon Halle8217482014-10-17 13:49:14 -04001037 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001038 main.log.error( self.name + ": EOF exception found" )
1039 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001040 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001041 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001042 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001043 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001044
kelvin-onlabd3b64892015-01-20 13:26:24 -08001045 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001046 """
Jon Hall983a1702014-10-28 18:44:22 -04001047 Lists all devices and the controllers with roles assigned to them
1048 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001049 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001050 """
andrewonlab7c211572014-10-15 16:45:20 -04001051 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001052 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001054 cmdStr += " -j"
1055 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001056 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001057 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001058 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001059 except AssertionError:
1060 main.log.exception( "" )
1061 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001062 except TypeError:
1063 main.log.exception( self.name + ": Object not as expected" )
1064 return None
Jon Hall983a1702014-10-28 18:44:22 -04001065 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001066 main.log.error( self.name + ": EOF exception found" )
1067 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001068 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001069 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001070 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001071 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -04001072
kelvin-onlabd3b64892015-01-20 13:26:24 -08001073 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001074 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001075 Given the a string containing the json representation of the "roles"
1076 cli command and a partial or whole device id, returns a json object
1077 containing the roles output for the first device whose id contains
1078 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001079
1080 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001081 A dict of the role assignments for the given device or
1082 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001083 """
Jon Hall983a1702014-10-28 18:44:22 -04001084 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001086 return None
1087 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001088 rawRoles = self.roles()
1089 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001090 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001091 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001092 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001094 return device
1095 return None
Jon Hallc6793552016-01-19 14:18:37 -08001096 except ( TypeError, ValueError ):
1097 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001098 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001099 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001100 main.log.error( self.name + ": EOF exception found" )
1101 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001102 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001103 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001104 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001105 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001106
kelvin-onlabd3b64892015-01-20 13:26:24 -08001107 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001108 """
Jon Hall94fd0472014-12-08 11:52:42 -08001109 Iterates through each device and checks if there is a master assigned
1110 Returns: main.TRUE if each device has a master
1111 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001112 """
Jon Hall94fd0472014-12-08 11:52:42 -08001113 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001114 rawRoles = self.roles()
1115 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001116 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001118 # print device
1119 if device[ 'master' ] == "none":
1120 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001121 return main.FALSE
1122 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001123 except ( TypeError, ValueError ):
1124 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001125 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001127 main.log.error( self.name + ": EOF exception found" )
1128 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001129 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001130 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001131 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001132 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001133
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001135 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001136 Returns string of paths, and the cost.
1137 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001138 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001139 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001140 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1141 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001142 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001143 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001144 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001145 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001146 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001147 else:
kelvin8ec71442015-01-15 16:57:00 -08001148 path = handle.split( ";" )[ 0 ]
1149 cost = handle.split( ";" )[ 1 ]
1150 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001151 except AssertionError:
1152 main.log.exception( "" )
1153 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001154 except TypeError:
1155 main.log.exception( self.name + ": Object not as expected" )
1156 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001157 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001158 main.log.error( self.name + ": EOF exception found" )
1159 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001160 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001161 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001162 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001163 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001164
kelvin-onlabd3b64892015-01-20 13:26:24 -08001165 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001166 """
Jon Hallffb386d2014-11-21 13:43:38 -08001167 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001168 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001169 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001170 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001171 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001172 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001173 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001174 cmdStr += " -j"
1175 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001176 if handle:
1177 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001178 # TODO: Maybe make this less hardcoded
1179 # ConsistentMap Exceptions
1180 assert "org.onosproject.store.service" not in handle
1181 # Node not leader
1182 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001183 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001184 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001185 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001186 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001187 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001188 except TypeError:
1189 main.log.exception( self.name + ": Object not as expected" )
1190 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001191 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001192 main.log.error( self.name + ": EOF exception found" )
1193 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001194 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001195 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001196 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001197 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001198
kelvin-onlabd3b64892015-01-20 13:26:24 -08001199 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001200 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001201 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001202
Jon Hallefbd9792015-03-05 16:11:36 -08001203 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001204 partial mac address
1205
Jon Hall42db6dc2014-10-24 19:03:48 -04001206 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001207 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001208 try:
kelvin8ec71442015-01-15 16:57:00 -08001209 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001210 return None
1211 else:
1212 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001213 rawHosts = self.hosts()
1214 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001215 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001216 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001217 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001218 if not host:
1219 pass
1220 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001221 return host
1222 return None
Jon Hallc6793552016-01-19 14:18:37 -08001223 except ( TypeError, ValueError ):
1224 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001225 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001226 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001227 main.log.error( self.name + ": EOF exception found" )
1228 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001229 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001230 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001231 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001232 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001233
kelvin-onlabd3b64892015-01-20 13:26:24 -08001234 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001235 """
1236 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001237 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001238
andrewonlab3f0a4af2014-10-17 12:25:14 -04001239 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001240 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001241 IMPORTANT:
1242 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001243 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001244 Furthermore, it assumes that value of VLAN is '-1'
1245 Description:
kelvin8ec71442015-01-15 16:57:00 -08001246 Converts mininet hosts ( h1, h2, h3... ) into
1247 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1248 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001249 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001250 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001251
kelvin-onlabd3b64892015-01-20 13:26:24 -08001252 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001253 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001254 hostHex = hex( int( host ) ).zfill( 12 )
1255 hostHex = str( hostHex ).replace( 'x', '0' )
1256 i = iter( str( hostHex ) )
1257 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1258 hostHex = hostHex + "/-1"
1259 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001260
kelvin-onlabd3b64892015-01-20 13:26:24 -08001261 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001262
Jon Halld4d4b372015-01-28 16:02:41 -08001263 except TypeError:
1264 main.log.exception( self.name + ": Object not as expected" )
1265 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001266 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001267 main.log.error( self.name + ": EOF exception found" )
1268 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001269 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001270 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001271 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001272 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001273
You Wangbc898b82018-05-03 16:22:34 -07001274 def verifyHostLocation( self, hostIp, location ):
1275 """
1276 Description:
1277 Verify the host given is discovered in all locations expected
1278 Required:
1279 hostIp: IP address of the host
1280 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1281 Could be a string or list
1282 Returns:
1283 main.TRUE if host is discovered on all locations provided
1284 main.FALSE otherwise
1285 """
1286 import json
1287 locations = [ location ] if isinstance( location, str ) else location
1288 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1289 try:
1290 hosts = self.hosts()
1291 hosts = json.loads( hosts )
1292 targetHost = None
1293 for host in hosts:
1294 if hostIp in host[ "ipAddresses" ]:
1295 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001296 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001297 result = main.TRUE
1298 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1299 for loc in locations:
1300 discovered = False
1301 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001302 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1303 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001304 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001305 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001306 break
1307 if discovered:
1308 locationsDiscovered.remove( locDiscovered )
1309 else:
1310 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1311 result = main.FALSE
1312 if locationsDiscovered:
1313 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1314 result = main.FALSE
1315 return result
1316 except KeyError:
1317 main.log.exception( self.name + ": host data not as expected: " + hosts )
1318 return None
1319 except pexpect.EOF:
1320 main.log.error( self.name + ": EOF exception found" )
1321 main.log.error( self.name + ": " + self.handle.before )
1322 main.cleanAndExit()
1323 except Exception:
1324 main.log.exception( self.name + ": Uncaught exception" )
1325 return None
1326
You Wang53dba1e2018-02-02 17:45:44 -08001327 def verifyHostIp( self, hostList=[], prefix="" ):
1328 """
1329 Description:
1330 Verify that all hosts have IP address assigned to them
1331 Optional:
1332 hostList: If specified, verifications only happen to the hosts
1333 in hostList
1334 prefix: at least one of the ip address assigned to the host
1335 needs to have the specified prefix
1336 Returns:
1337 main.TRUE if all hosts have specific IP address assigned;
1338 main.FALSE otherwise
1339 """
1340 import json
1341 try:
1342 hosts = self.hosts()
1343 hosts = json.loads( hosts )
1344 if not hostList:
1345 hostList = [ host[ "id" ] for host in hosts ]
1346 for host in hosts:
1347 hostId = host[ "id" ]
1348 if hostId not in hostList:
1349 continue
1350 ipList = host[ "ipAddresses" ]
1351 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1352 if not ipList:
1353 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1354 else:
1355 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1356 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1357 else:
1358 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1359 hostList.remove( hostId )
1360 if hostList:
1361 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1362 return main.FALSE
1363 else:
1364 return main.TRUE
1365 except KeyError:
1366 main.log.exception( self.name + ": host data not as expected: " + hosts )
1367 return None
1368 except pexpect.EOF:
1369 main.log.error( self.name + ": EOF exception found" )
1370 main.log.error( self.name + ": " + self.handle.before )
1371 main.cleanAndExit()
1372 except Exception:
1373 main.log.exception( self.name + ": Uncaught exception" )
1374 return None
1375
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001376 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001377 """
andrewonlabe6745342014-10-17 14:29:13 -04001378 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001379 * hostIdOne: ONOS host id for host1
1380 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001381 Optional:
1382 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001383 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001384 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001385 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001386 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001387 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001388 Returns:
1389 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001390 """
andrewonlabe6745342014-10-17 14:29:13 -04001391 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001392 cmdStr = "add-host-intent "
1393 if vlanId:
1394 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001395 if setVlan:
1396 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001397 if encap:
1398 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001399 if bandwidth:
1400 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001401 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001402 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001403 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001404 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001405 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001406 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001407 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001408 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001409 else:
1410 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001411 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001412 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001413 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001414 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001415 else:
1416 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001417 main.log.debug( "Response from ONOS was: " +
1418 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001419 return None
Jon Hallc6793552016-01-19 14:18:37 -08001420 except AssertionError:
1421 main.log.exception( "" )
1422 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001423 except TypeError:
1424 main.log.exception( self.name + ": Object not as expected" )
1425 return None
andrewonlabe6745342014-10-17 14:29:13 -04001426 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001427 main.log.error( self.name + ": EOF exception found" )
1428 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001429 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001430 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001431 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001432 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001433
kelvin-onlabd3b64892015-01-20 13:26:24 -08001434 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001435 """
andrewonlab7b31d232014-10-24 13:31:47 -04001436 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001437 * ingressDevice: device id of ingress device
1438 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001439 Optional:
1440 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001441 Description:
1442 Adds an optical intent by specifying an ingress and egress device
1443 Returns:
1444 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001445 """
andrewonlab7b31d232014-10-24 13:31:47 -04001446 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001447 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1448 " " + str( egressDevice )
1449 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001450 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001451 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001452 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001453 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001454 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001455 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001456 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001457 main.log.info( "Optical intent installed between " +
1458 str( ingressDevice ) + " and " +
1459 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001460 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001461 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001462 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001463 else:
1464 main.log.error( "Error, intent ID not found" )
1465 return None
Jon Hallc6793552016-01-19 14:18:37 -08001466 except AssertionError:
1467 main.log.exception( "" )
1468 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001469 except TypeError:
1470 main.log.exception( self.name + ": Object not as expected" )
1471 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001472 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001473 main.log.error( self.name + ": EOF exception found" )
1474 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001475 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001476 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001477 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001478 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001479
kelvin-onlabd3b64892015-01-20 13:26:24 -08001480 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001481 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001482 ingressDevice,
1483 egressDevice,
1484 portIngress="",
1485 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001486 ethType="",
1487 ethSrc="",
1488 ethDst="",
1489 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001490 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001491 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001492 ipProto="",
1493 ipSrc="",
1494 ipDst="",
1495 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001496 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001497 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001498 setVlan="",
1499 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001500 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001501 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001502 * ingressDevice: device id of ingress device
1503 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001504 Optional:
1505 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001506 * ethSrc: specify ethSrc ( i.e. src mac addr )
1507 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001508 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001509 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001510 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001511 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001512 * ipSrc: specify ip source address
1513 * ipDst: specify ip destination address
1514 * tcpSrc: specify tcp source port
1515 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001516 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001517 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001518 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001519 Description:
kelvin8ec71442015-01-15 16:57:00 -08001520 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001521 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001522 Returns:
1523 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001524
Jon Halle3f39ff2015-01-13 11:50:53 -08001525 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001526 options developers provide for point-to-point
1527 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001528 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001529 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001530 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001531
Jeremy Songsterff553672016-05-12 17:06:23 -07001532 if ethType:
1533 cmd += " --ethType " + str( ethType )
1534 if ethSrc:
1535 cmd += " --ethSrc " + str( ethSrc )
1536 if ethDst:
1537 cmd += " --ethDst " + str( ethDst )
1538 if bandwidth:
1539 cmd += " --bandwidth " + str( bandwidth )
1540 if lambdaAlloc:
1541 cmd += " --lambda "
1542 if ipProto:
1543 cmd += " --ipProto " + str( ipProto )
1544 if ipSrc:
1545 cmd += " --ipSrc " + str( ipSrc )
1546 if ipDst:
1547 cmd += " --ipDst " + str( ipDst )
1548 if tcpSrc:
1549 cmd += " --tcpSrc " + str( tcpSrc )
1550 if tcpDst:
1551 cmd += " --tcpDst " + str( tcpDst )
1552 if vlanId:
1553 cmd += " -v " + str( vlanId )
1554 if setVlan:
1555 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001556 if encap:
1557 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001558 if protected:
1559 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001560
kelvin8ec71442015-01-15 16:57:00 -08001561 # Check whether the user appended the port
1562 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001563 if "/" in ingressDevice:
1564 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001565 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001566 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001567 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001568 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001569 # Would it make sense to throw an exception and exit
1570 # the test?
1571 return None
andrewonlab36af3822014-11-18 17:48:18 -05001572
kelvin8ec71442015-01-15 16:57:00 -08001573 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 str( ingressDevice ) + "/" +\
1575 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001576
kelvin-onlabd3b64892015-01-20 13:26:24 -08001577 if "/" in egressDevice:
1578 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001579 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001580 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001581 main.log.error( "You must specify the egress port" )
1582 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001583
kelvin8ec71442015-01-15 16:57:00 -08001584 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001585 str( egressDevice ) + "/" +\
1586 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001587
kelvin-onlab898a6c62015-01-16 14:13:53 -08001588 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001589 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001590 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001591 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001592 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001593 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001594 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001595 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001596 # TODO: print out all the options in this message?
1597 main.log.info( "Point-to-point intent installed between " +
1598 str( ingressDevice ) + " and " +
1599 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001600 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001601 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001602 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001603 else:
1604 main.log.error( "Error, intent ID not found" )
1605 return None
Jon Hallc6793552016-01-19 14:18:37 -08001606 except AssertionError:
1607 main.log.exception( "" )
1608 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001609 except TypeError:
1610 main.log.exception( self.name + ": Object not as expected" )
1611 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001612 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001613 main.log.error( self.name + ": EOF exception found" )
1614 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001615 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001616 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001617 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001618 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001619
kelvin-onlabd3b64892015-01-20 13:26:24 -08001620 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001621 self,
shahshreyac2f97072015-03-19 17:04:29 -07001622 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001623 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001624 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001625 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001626 ethType="",
1627 ethSrc="",
1628 ethDst="",
1629 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001630 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001631 ipProto="",
1632 ipSrc="",
1633 ipDst="",
1634 tcpSrc="",
1635 tcpDst="",
1636 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001637 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001638 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001639 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001640 partial=False,
1641 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001642 """
shahshreyad0c80432014-12-04 16:56:05 -08001643 Note:
shahshreya70622b12015-03-19 17:19:00 -07001644 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001645 is same. That is, all ingress devices include port numbers
1646 with a "/" or all ingress devices could specify device
1647 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001648 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001649 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001650 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001651 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001652 Optional:
1653 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001654 * ethSrc: specify ethSrc ( i.e. src mac addr )
1655 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001656 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001657 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001658 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001659 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001660 * ipSrc: specify ip source address
1661 * ipDst: specify ip destination address
1662 * tcpSrc: specify tcp source port
1663 * tcpDst: specify tcp destination port
1664 * setEthSrc: action to Rewrite Source MAC Address
1665 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001666 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001667 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001668 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001669 Description:
kelvin8ec71442015-01-15 16:57:00 -08001670 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001671 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001672 Returns:
1673 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001674
Jon Halle3f39ff2015-01-13 11:50:53 -08001675 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001676 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001677 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001678 """
shahshreyad0c80432014-12-04 16:56:05 -08001679 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001680 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001681
Jeremy Songsterff553672016-05-12 17:06:23 -07001682 if ethType:
1683 cmd += " --ethType " + str( ethType )
1684 if ethSrc:
1685 cmd += " --ethSrc " + str( ethSrc )
1686 if ethDst:
1687 cmd += " --ethDst " + str( ethDst )
1688 if bandwidth:
1689 cmd += " --bandwidth " + str( bandwidth )
1690 if lambdaAlloc:
1691 cmd += " --lambda "
1692 if ipProto:
1693 cmd += " --ipProto " + str( ipProto )
1694 if ipSrc:
1695 cmd += " --ipSrc " + str( ipSrc )
1696 if ipDst:
1697 cmd += " --ipDst " + str( ipDst )
1698 if tcpSrc:
1699 cmd += " --tcpSrc " + str( tcpSrc )
1700 if tcpDst:
1701 cmd += " --tcpDst " + str( tcpDst )
1702 if setEthSrc:
1703 cmd += " --setEthSrc " + str( setEthSrc )
1704 if setEthDst:
1705 cmd += " --setEthDst " + str( setEthDst )
1706 if vlanId:
1707 cmd += " -v " + str( vlanId )
1708 if setVlan:
1709 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001710 if partial:
1711 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001712 if encap:
1713 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001714
kelvin8ec71442015-01-15 16:57:00 -08001715 # Check whether the user appended the port
1716 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001717
1718 if portIngressList is None:
1719 for ingressDevice in ingressDeviceList:
1720 if "/" in ingressDevice:
1721 cmd += " " + str( ingressDevice )
1722 else:
1723 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001724 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001725 # TODO: perhaps more meaningful return
1726 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001727 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001728 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001729 for ingressDevice, portIngress in zip( ingressDeviceList,
1730 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001731 cmd += " " + \
1732 str( ingressDevice ) + "/" +\
1733 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001734 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001735 main.log.error( "Device list and port list does not " +
1736 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001737 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001738 if "/" in egressDevice:
1739 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001740 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001741 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001742 main.log.error( "You must specify " +
1743 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001744 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001745
kelvin8ec71442015-01-15 16:57:00 -08001746 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001747 str( egressDevice ) + "/" +\
1748 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001749 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001750 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001751 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001752 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001753 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001754 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001755 "intent" )
1756 return None
shahshreyad0c80432014-12-04 16:56:05 -08001757 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001758 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001759 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001760 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001761 else:
1762 main.log.error( "Error, intent ID not found" )
1763 return None
Jon Hallc6793552016-01-19 14:18:37 -08001764 except AssertionError:
1765 main.log.exception( "" )
1766 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001767 except TypeError:
1768 main.log.exception( self.name + ": Object not as expected" )
1769 return None
1770 except pexpect.EOF:
1771 main.log.error( self.name + ": EOF exception found" )
1772 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001773 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001774 except Exception:
1775 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001776 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001777
1778 def addSinglepointToMultipointIntent(
1779 self,
1780 ingressDevice,
1781 egressDeviceList,
1782 portIngress="",
1783 portEgressList=None,
1784 ethType="",
1785 ethSrc="",
1786 ethDst="",
1787 bandwidth="",
1788 lambdaAlloc=False,
1789 ipProto="",
1790 ipSrc="",
1791 ipDst="",
1792 tcpSrc="",
1793 tcpDst="",
1794 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001795 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001796 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001797 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001798 partial=False,
1799 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001800 """
1801 Note:
1802 This function assumes the format of all egress devices
1803 is same. That is, all egress devices include port numbers
1804 with a "/" or all egress devices could specify device
1805 ids and port numbers seperately.
1806 Required:
1807 * EgressDeviceList: List of device ids of egress device
1808 ( Atleast 2 eress devices required in the list )
1809 * ingressDevice: device id of ingress device
1810 Optional:
1811 * ethType: specify ethType
1812 * ethSrc: specify ethSrc ( i.e. src mac addr )
1813 * ethDst: specify ethDst ( i.e. dst mac addr )
1814 * bandwidth: specify bandwidth capacity of link
1815 * lambdaAlloc: if True, intent will allocate lambda
1816 for the specified intent
1817 * ipProto: specify ip protocol
1818 * ipSrc: specify ip source address
1819 * ipDst: specify ip destination address
1820 * tcpSrc: specify tcp source port
1821 * tcpDst: specify tcp destination port
1822 * setEthSrc: action to Rewrite Source MAC Address
1823 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001824 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001825 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001826 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001827 Description:
1828 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1829 specifying device id's and optional fields
1830 Returns:
1831 A string of the intent id or None on error
1832
1833 NOTE: This function may change depending on the
1834 options developers provide for singlepoint-to-multipoint
1835 intent via cli
1836 """
1837 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001838 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001839
Jeremy Songsterff553672016-05-12 17:06:23 -07001840 if ethType:
1841 cmd += " --ethType " + str( ethType )
1842 if ethSrc:
1843 cmd += " --ethSrc " + str( ethSrc )
1844 if ethDst:
1845 cmd += " --ethDst " + str( ethDst )
1846 if bandwidth:
1847 cmd += " --bandwidth " + str( bandwidth )
1848 if lambdaAlloc:
1849 cmd += " --lambda "
1850 if ipProto:
1851 cmd += " --ipProto " + str( ipProto )
1852 if ipSrc:
1853 cmd += " --ipSrc " + str( ipSrc )
1854 if ipDst:
1855 cmd += " --ipDst " + str( ipDst )
1856 if tcpSrc:
1857 cmd += " --tcpSrc " + str( tcpSrc )
1858 if tcpDst:
1859 cmd += " --tcpDst " + str( tcpDst )
1860 if setEthSrc:
1861 cmd += " --setEthSrc " + str( setEthSrc )
1862 if setEthDst:
1863 cmd += " --setEthDst " + str( setEthDst )
1864 if vlanId:
1865 cmd += " -v " + str( vlanId )
1866 if setVlan:
1867 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001868 if partial:
1869 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001870 if encap:
1871 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001872
1873 # Check whether the user appended the port
1874 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001875
kelvin-onlabb9408212015-04-01 13:34:04 -07001876 if "/" in ingressDevice:
1877 cmd += " " + str( ingressDevice )
1878 else:
1879 if not portIngress:
1880 main.log.error( "You must specify " +
1881 "the Ingress port" )
1882 return main.FALSE
1883
1884 cmd += " " +\
1885 str( ingressDevice ) + "/" +\
1886 str( portIngress )
1887
1888 if portEgressList is None:
1889 for egressDevice in egressDeviceList:
1890 if "/" in egressDevice:
1891 cmd += " " + str( egressDevice )
1892 else:
1893 main.log.error( "You must specify " +
1894 "the egress port" )
1895 # TODO: perhaps more meaningful return
1896 return main.FALSE
1897 else:
1898 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001899 for egressDevice, portEgress in zip( egressDeviceList,
1900 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001901 cmd += " " + \
1902 str( egressDevice ) + "/" +\
1903 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001904 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001905 main.log.error( "Device list and port list does not " +
1906 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001907 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001908 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001909 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001910 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001911 # If error, return error message
1912 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001913 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001914 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001915 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001916 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001917 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001918 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001919 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001920 else:
1921 main.log.error( "Error, intent ID not found" )
1922 return None
Jon Hallc6793552016-01-19 14:18:37 -08001923 except AssertionError:
1924 main.log.exception( "" )
1925 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001926 except TypeError:
1927 main.log.exception( self.name + ": Object not as expected" )
1928 return None
shahshreyad0c80432014-12-04 16:56:05 -08001929 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001930 main.log.error( self.name + ": EOF exception found" )
1931 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001932 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001933 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001934 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001935 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001936
Hari Krishna9e232602015-04-13 17:29:08 -07001937 def addMplsIntent(
1938 self,
1939 ingressDevice,
1940 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001941 ingressPort="",
1942 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001943 ethType="",
1944 ethSrc="",
1945 ethDst="",
1946 bandwidth="",
1947 lambdaAlloc=False,
1948 ipProto="",
1949 ipSrc="",
1950 ipDst="",
1951 tcpSrc="",
1952 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001953 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001954 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001955 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001956 """
1957 Required:
1958 * ingressDevice: device id of ingress device
1959 * egressDevice: device id of egress device
1960 Optional:
1961 * ethType: specify ethType
1962 * ethSrc: specify ethSrc ( i.e. src mac addr )
1963 * ethDst: specify ethDst ( i.e. dst mac addr )
1964 * bandwidth: specify bandwidth capacity of link
1965 * lambdaAlloc: if True, intent will allocate lambda
1966 for the specified intent
1967 * ipProto: specify ip protocol
1968 * ipSrc: specify ip source address
1969 * ipDst: specify ip destination address
1970 * tcpSrc: specify tcp source port
1971 * tcpDst: specify tcp destination port
1972 * ingressLabel: Ingress MPLS label
1973 * egressLabel: Egress MPLS label
1974 Description:
1975 Adds MPLS intent by
1976 specifying device id's and optional fields
1977 Returns:
1978 A string of the intent id or None on error
1979
1980 NOTE: This function may change depending on the
1981 options developers provide for MPLS
1982 intent via cli
1983 """
1984 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001985 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001986
Jeremy Songsterff553672016-05-12 17:06:23 -07001987 if ethType:
1988 cmd += " --ethType " + str( ethType )
1989 if ethSrc:
1990 cmd += " --ethSrc " + str( ethSrc )
1991 if ethDst:
1992 cmd += " --ethDst " + str( ethDst )
1993 if bandwidth:
1994 cmd += " --bandwidth " + str( bandwidth )
1995 if lambdaAlloc:
1996 cmd += " --lambda "
1997 if ipProto:
1998 cmd += " --ipProto " + str( ipProto )
1999 if ipSrc:
2000 cmd += " --ipSrc " + str( ipSrc )
2001 if ipDst:
2002 cmd += " --ipDst " + str( ipDst )
2003 if tcpSrc:
2004 cmd += " --tcpSrc " + str( tcpSrc )
2005 if tcpDst:
2006 cmd += " --tcpDst " + str( tcpDst )
2007 if ingressLabel:
2008 cmd += " --ingressLabel " + str( ingressLabel )
2009 if egressLabel:
2010 cmd += " --egressLabel " + str( egressLabel )
2011 if priority:
2012 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07002013
2014 # Check whether the user appended the port
2015 # or provided it as an input
2016 if "/" in ingressDevice:
2017 cmd += " " + str( ingressDevice )
2018 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002019 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002020 main.log.error( "You must specify the ingress port" )
2021 return None
2022
2023 cmd += " " + \
2024 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002025 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07002026
2027 if "/" in egressDevice:
2028 cmd += " " + str( egressDevice )
2029 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002030 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002031 main.log.error( "You must specify the egress port" )
2032 return None
2033
2034 cmd += " " +\
2035 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002036 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07002037
2038 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08002039 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002040 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07002041 # If error, return error message
2042 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002043 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07002044 return None
2045 else:
2046 # TODO: print out all the options in this message?
2047 main.log.info( "MPLS intent installed between " +
2048 str( ingressDevice ) + " and " +
2049 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002050 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07002051 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002052 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07002053 else:
2054 main.log.error( "Error, intent ID not found" )
2055 return None
Jon Hallc6793552016-01-19 14:18:37 -08002056 except AssertionError:
2057 main.log.exception( "" )
2058 return None
Hari Krishna9e232602015-04-13 17:29:08 -07002059 except TypeError:
2060 main.log.exception( self.name + ": Object not as expected" )
2061 return None
2062 except pexpect.EOF:
2063 main.log.error( self.name + ": EOF exception found" )
2064 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002065 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002066 except Exception:
2067 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002068 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002069
Jon Hallefbd9792015-03-05 16:11:36 -08002070 def removeIntent( self, intentId, app='org.onosproject.cli',
2071 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002072 """
shahshreya1c818fc2015-02-26 13:44:08 -08002073 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07002074 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08002075 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07002076 -p or --purge: Purge the intent from the store after removal
2077
Jon Halle3f39ff2015-01-13 11:50:53 -08002078 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002079 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002080 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002081 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002082 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002083 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002084 if purge:
2085 cmdStr += " -p"
2086 if sync:
2087 cmdStr += " -s"
2088
2089 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002090 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002091 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002092 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002093 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002094 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002095 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002096 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002097 # TODO: Should this be main.TRUE
2098 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002099 except AssertionError:
2100 main.log.exception( "" )
2101 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002102 except TypeError:
2103 main.log.exception( self.name + ": Object not as expected" )
2104 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002105 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002106 main.log.error( self.name + ": EOF exception found" )
2107 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002108 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002109 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002110 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002111 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002112
YPZhangfebf7302016-05-24 16:45:56 -07002113 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002114 """
2115 Description:
2116 Remove all the intents
2117 Optional args:-
2118 -s or --sync: Waits for the removal before returning
2119 -p or --purge: Purge the intent from the store after removal
2120 Returns:
2121 Returns main.TRUE if all intents are removed, otherwise returns
2122 main.FALSE; Returns None for exception
2123 """
2124 try:
2125 cmdStr = "remove-intent"
2126 if purge:
2127 cmdStr += " -p"
2128 if sync:
2129 cmdStr += " -s"
2130
2131 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002132 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002133 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002134 assert "Command not found:" not in handle, handle
2135 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002136 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002137 return main.FALSE
2138 else:
2139 return main.TRUE
2140 except AssertionError:
2141 main.log.exception( "" )
2142 return None
2143 except TypeError:
2144 main.log.exception( self.name + ": Object not as expected" )
2145 return None
2146 except pexpect.EOF:
2147 main.log.error( self.name + ": EOF exception found" )
2148 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002149 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002150 except Exception:
2151 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002152 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002153
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002154 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002155 """
2156 Purges all WITHDRAWN Intents
2157 """
2158 try:
2159 cmdStr = "purge-intents"
2160 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002161 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002162 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002163 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002164 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002165 return main.FALSE
2166 else:
2167 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002168 except AssertionError:
2169 main.log.exception( "" )
2170 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002171 except TypeError:
2172 main.log.exception( self.name + ": Object not as expected" )
2173 return None
2174 except pexpect.EOF:
2175 main.log.error( self.name + ": EOF exception found" )
2176 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002177 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002178 except Exception:
2179 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002180 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002181
Devin Lime6fe3c42017-10-18 16:28:40 -07002182 def wipeout( self ):
2183 """
2184 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2185 """
2186 try:
2187 cmdStr = "wipe-out please"
2188 handle = self.sendline( cmdStr, timeout=60 )
2189 assert handle is not None, "Error in sendline"
2190 assert "Command not found:" not in handle, handle
2191 return main.TRUE
2192 except AssertionError:
2193 main.log.exception( "" )
2194 return None
2195 except TypeError:
2196 main.log.exception( self.name + ": Object not as expected" )
2197 return None
2198 except pexpect.EOF:
2199 main.log.error( self.name + ": EOF exception found" )
2200 main.log.error( self.name + ": " + self.handle.before )
2201 main.cleanAndExit()
2202 except Exception:
2203 main.log.exception( self.name + ": Uncaught exception!" )
2204 main.cleanAndExit()
2205
kelvin-onlabd3b64892015-01-20 13:26:24 -08002206 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002207 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002208 NOTE: This method should be used after installing application:
2209 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002210 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002211 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002212 Description:
2213 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002214 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002215 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002216 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002217 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002218 cmdStr += " -j"
2219 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002220 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002221 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002222 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002223 except AssertionError:
2224 main.log.exception( "" )
2225 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002226 except TypeError:
2227 main.log.exception( self.name + ": Object not as expected" )
2228 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002229 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002230 main.log.error( self.name + ": EOF exception found" )
2231 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002232 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002233 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002234 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002235 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002236
pingping-lin54b03372015-08-13 14:43:10 -07002237 def ipv4RouteNumber( self ):
2238 """
2239 NOTE: This method should be used after installing application:
2240 onos-app-sdnip
2241 Description:
2242 Obtain the total IPv4 routes number in the system
2243 """
2244 try:
Pratik Parab57963572017-05-09 11:37:54 -07002245 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002246 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002247 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002248 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002249 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002250 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002251 except AssertionError:
2252 main.log.exception( "" )
2253 return None
2254 except ( TypeError, ValueError ):
2255 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002256 return None
2257 except pexpect.EOF:
2258 main.log.error( self.name + ": EOF exception found" )
2259 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002260 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002261 except Exception:
2262 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002263 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002264
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002265 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002266 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002267 """
2268 Description:
2269 Obtain Bandwidth Allocation Information from ONOS cli.
2270 """
2271 try:
2272 cmdStr = "allocations"
2273 if jsonFormat:
2274 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002275 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002276 assert handle is not None, "Error in sendline"
2277 assert "Command not found:" not in handle, handle
2278 return handle
2279 except AssertionError:
2280 main.log.exception( "" )
2281 return None
2282 except ( TypeError, ValueError ):
2283 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2284 return None
2285 except pexpect.EOF:
2286 main.log.error( self.name + ": EOF exception found" )
2287 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002288 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002289 except Exception:
2290 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002291 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002292
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002293 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002294 """
andrewonlabe6745342014-10-17 14:29:13 -04002295 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002296 Obtain intents from the ONOS cli.
2297 Optional:
2298 * jsonFormat: Enable output formatting in json, default to True
2299 * summary: Whether only output the intent summary, defaults to False
2300 * type: Only output a certain type of intent. This options is valid
2301 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002302 """
andrewonlabe6745342014-10-17 14:29:13 -04002303 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002304 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002305 if summary:
2306 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002307 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002308 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002309 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002310 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002311 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002312 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002313 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002314 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002315 else:
Jon Hallff566d52016-01-15 14:45:36 -08002316 intentType = ""
2317 # IF we want the summary of a specific intent type
2318 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002319 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002320 if intentType in jsonResult.keys():
2321 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002322 else:
Jon Hallff566d52016-01-15 14:45:36 -08002323 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002324 return handle
2325 else:
2326 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002327 except AssertionError:
2328 main.log.exception( "" )
2329 return None
2330 except ( TypeError, ValueError ):
2331 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002332 return None
2333 except pexpect.EOF:
2334 main.log.error( self.name + ": EOF exception found" )
2335 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002336 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002337 except Exception:
2338 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002339 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002340
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002341 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002342 """
You Wangfdcbfc42016-05-16 12:16:53 -07002343 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002344 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002345 list of intent IDs.
2346 Parameters:
2347 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002348 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002349 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002350 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002351 accepted.
2352 Returns a list of dictionaries if a list of intent IDs is accepted,
2353 and each dictionary maps 'id' to the Intent ID and 'state' to
2354 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002355 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002356
kelvin-onlab54400a92015-02-26 18:05:51 -08002357 try:
2358 state = "State is Undefined"
2359 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002360 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002361 else:
Jon Hallc6793552016-01-19 14:18:37 -08002362 rawJson = intentsJson
2363 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002364 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002365 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002366 if intentsId == intent[ 'id' ]:
2367 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002368 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002369 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002370 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002371 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002372 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002373 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002374 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002375 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002376 for intent in parsedIntentsJson:
2377 if intentsId[ i ] == intent[ 'id' ]:
2378 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002379 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002380 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002381 break
Jon Hallefbd9792015-03-05 16:11:36 -08002382 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002383 main.log.warn( "Could not find all intents in ONOS output" )
2384 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002385 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002386 else:
Jon Hall53158082017-05-18 11:17:00 -07002387 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002388 return None
Jon Hallc6793552016-01-19 14:18:37 -08002389 except ( TypeError, ValueError ):
2390 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002391 return None
2392 except pexpect.EOF:
2393 main.log.error( self.name + ": EOF exception found" )
2394 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002395 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002396 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002397 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002398 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002399
Jon Hallf539eb92017-05-22 17:18:42 -07002400 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002401 """
2402 Description:
2403 Check intents state
2404 Required:
2405 intentsId - List of intents ID to be checked
2406 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002407 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002408 state in the list.
2409 *NOTE: You can pass in a list of expected state,
2410 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002411 Return:
Jon Hall53158082017-05-18 11:17:00 -07002412 Returns main.TRUE only if all intent are the same as expected states,
2413 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002414 """
2415 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002416 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002417 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002418
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002419 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002420 intentsDict = []
2421 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002422 if isinstance( intentsId, types.StringType ) \
2423 and intent.get( 'id' ) == intentsId:
2424 intentsDict.append( intent )
2425 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002426 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002427 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002428
2429 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002430 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002431 "getting intents state" )
2432 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002433
2434 if isinstance( expectedState, types.StringType ):
2435 for intents in intentsDict:
2436 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002437 main.log.debug( self.name + " : Intent ID - " +
2438 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002439 " actual state = " +
2440 intents.get( 'state' )
2441 + " does not equal expected state = "
2442 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002443 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002444 elif isinstance( expectedState, types.ListType ):
2445 for intents in intentsDict:
2446 if not any( state == intents.get( 'state' ) for state in
2447 expectedState ):
2448 main.log.debug( self.name + " : Intent ID - " +
2449 intents.get( 'id' ) +
2450 " actual state = " +
2451 intents.get( 'state' ) +
2452 " does not equal expected states = "
2453 + str( expectedState ) )
2454 returnValue = main.FALSE
2455
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002456 if returnValue == main.TRUE:
2457 main.log.info( self.name + ": All " +
2458 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002459 " intents are in " + str( expectedState ) +
2460 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002461 return returnValue
2462 except TypeError:
2463 main.log.exception( self.name + ": Object not as expected" )
2464 return None
2465 except pexpect.EOF:
2466 main.log.error( self.name + ": EOF exception found" )
2467 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002468 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002469 except Exception:
2470 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002471 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002472
Jon Hallf539eb92017-05-22 17:18:42 -07002473 def compareBandwidthAllocations( self, expectedAllocations ):
2474 """
2475 Description:
2476 Compare the allocated bandwidth with the given allocations
2477 Required:
2478 expectedAllocations - The expected ONOS output of the allocations command
2479 Return:
2480 Returns main.TRUE only if all intent are the same as expected states,
2481 otherwise returns main.FALSE.
2482 """
2483 # FIXME: Convert these string comparisons to object comparisons
2484 try:
2485 returnValue = main.TRUE
2486 bandwidthFailed = False
2487 rawAlloc = self.allocations()
2488 expectedFormat = StringIO( expectedAllocations )
2489 ONOSOutput = StringIO( rawAlloc )
2490 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2491 str( expectedFormat ) ) )
2492
2493 for actual, expected in izip( ONOSOutput, expectedFormat ):
2494 actual = actual.rstrip()
2495 expected = expected.rstrip()
2496 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2497 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002498 marker1 = actual.find( 'allocated' )
2499 m1 = actual[ :marker1 ]
2500 marker2 = expected.find( 'allocated' )
2501 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002502 if m1 != m2:
2503 bandwidthFailed = True
2504 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2505 bandwidthFailed = True
2506 expectedFormat.close()
2507 ONOSOutput.close()
2508
2509 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002510 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002511 returnValue = main.FALSE
2512 return returnValue
2513 except TypeError:
2514 main.log.exception( self.name + ": Object not as expected" )
2515 return None
2516 except pexpect.EOF:
2517 main.log.error( self.name + ": EOF exception found" )
2518 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002519 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002520 except Exception:
2521 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002522 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002523
You Wang66518af2016-05-16 15:32:59 -07002524 def compareIntent( self, intentDict ):
2525 """
2526 Description:
2527 Compare the intent ids and states provided in the argument with all intents in ONOS
2528 Return:
2529 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2530 Arguments:
2531 intentDict: a dictionary which maps intent ids to intent states
2532 """
2533 try:
2534 intentsRaw = self.intents()
2535 intentsJson = json.loads( intentsRaw )
2536 intentDictONOS = {}
2537 for intent in intentsJson:
2538 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002539 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002540 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002541 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002542 str( len( intentDict ) ) + " expected and " +
2543 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002544 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002545 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002546 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002547 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2548 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002549 else:
2550 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2551 main.log.debug( self.name + ": intent ID - " + intentID +
2552 " expected state is " + intentDict[ intentID ] +
2553 " but actual state is " + intentDictONOS[ intentID ] )
2554 returnValue = main.FALSE
2555 intentDictONOS.pop( intentID )
2556 if len( intentDictONOS ) > 0:
2557 returnValue = main.FALSE
2558 for intentID in intentDictONOS.keys():
2559 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002560 if returnValue == main.TRUE:
2561 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2562 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002563 except KeyError:
2564 main.log.exception( self.name + ": KeyError exception found" )
2565 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002566 except ( TypeError, ValueError ):
2567 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002568 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002569 except pexpect.EOF:
2570 main.log.error( self.name + ": EOF exception found" )
2571 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002572 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002573 except Exception:
2574 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002575 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002576
YPZhang14a4aa92016-07-15 13:37:15 -07002577 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002578 """
2579 Description:
2580 Check the number of installed intents.
2581 Optional:
2582 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002583 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002584 Return:
2585 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2586 , otherwise, returns main.FALSE.
2587 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002588
GlennRCed771242016-01-13 17:02:47 -08002589 try:
2590 cmd = "intents -s -j"
2591
2592 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002593 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002594 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002595 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002596 response = json.loads( response )
2597
2598 # get total and installed number, see if they are match
2599 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002600 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002601 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2602 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002603 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002604 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2605 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002606 return main.FALSE
2607
Jon Hallc6793552016-01-19 14:18:37 -08002608 except ( TypeError, ValueError ):
2609 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002610 return None
2611 except pexpect.EOF:
2612 main.log.error( self.name + ": EOF exception found" )
2613 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002614 if noExit:
2615 return main.FALSE
2616 else:
Devin Lim44075962017-08-11 10:56:37 -07002617 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002618 except pexpect.TIMEOUT:
2619 main.log.error( self.name + ": ONOS timeout" )
2620 return None
GlennRCed771242016-01-13 17:02:47 -08002621 except Exception:
2622 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002623 if noExit:
2624 return main.FALSE
2625 else:
Devin Lim44075962017-08-11 10:56:37 -07002626 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002627
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002628 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002629 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002630 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002631 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002632 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002633 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002634 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002635 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002636 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002637 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002638 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002639 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002640 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002641 cmdStr += " -n"
2642 cmdStr += " " + state
2643 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002644 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002645 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002646 assert "Command not found:" not in handle, handle
2647 if re.search( "Error:", handle ):
2648 main.log.error( self.name + ": flows() response: " +
2649 str( handle ) )
2650 return handle
2651 except AssertionError:
2652 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002653 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002654 except TypeError:
2655 main.log.exception( self.name + ": Object not as expected" )
2656 return None
Jon Hallc6793552016-01-19 14:18:37 -08002657 except pexpect.TIMEOUT:
2658 main.log.error( self.name + ": ONOS timeout" )
2659 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002660 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002661 main.log.error( self.name + ": EOF exception found" )
2662 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002663 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002664 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002665 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002666 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002667
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002668 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002669 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002670 count = int( count ) if count else 0
2671 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002672
Jon Halle0f0b342017-04-18 11:43:47 -07002673 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002674 """
2675 Description:
GlennRCed771242016-01-13 17:02:47 -08002676 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002677 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2678 if the count of those states is 0, which means all current flows
2679 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002680 Optional:
GlennRCed771242016-01-13 17:02:47 -08002681 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002682 Return:
2683 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002684 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002685 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002686 """
2687 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002688 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002689 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002690 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002691 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002692 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002693 if rawFlows:
2694 # if we didn't get flows or flows function return None, we should return
2695 # main.Flase
2696 checkedStates.append( json.loads( rawFlows ) )
2697 else:
2698 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002699 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002700 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002701 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002702 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002703 except TypeError:
2704 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002705 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002706
GlennRCed771242016-01-13 17:02:47 -08002707 # We want to count PENDING_ADD if isPENDING is true
2708 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002709 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002710 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002711 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002712 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002713 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002714 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002715 except ( TypeError, ValueError ):
2716 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002717 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002718
YPZhang240842b2016-05-17 12:00:50 -07002719 except AssertionError:
2720 main.log.exception( "" )
2721 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002722 except pexpect.TIMEOUT:
2723 main.log.error( self.name + ": ONOS timeout" )
2724 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002725 except pexpect.EOF:
2726 main.log.error( self.name + ": EOF exception found" )
2727 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002728 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002729 except Exception:
2730 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002731 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002732
GlennRCed771242016-01-13 17:02:47 -08002733 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002734 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002735 """
andrewonlab87852b02014-11-19 18:44:19 -05002736 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002737 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002738 a specific point-to-point intent definition
2739 Required:
GlennRCed771242016-01-13 17:02:47 -08002740 * ingress: specify source dpid
2741 * egress: specify destination dpid
2742 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002743 Optional:
GlennRCed771242016-01-13 17:02:47 -08002744 * offset: the keyOffset is where the next batch of intents
2745 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002746 * noExit: If set to True, TestON will not exit if any error when issus command
2747 * getResponse: If set to True, function will return ONOS response.
2748
GlennRCed771242016-01-13 17:02:47 -08002749 Returns: If failed to push test intents, it will returen None,
2750 if successful, return true.
2751 Timeout expection will return None,
2752 TypeError will return false
2753 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002754 """
andrewonlab87852b02014-11-19 18:44:19 -05002755 try:
GlennRCed771242016-01-13 17:02:47 -08002756 if background:
2757 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002758 else:
GlennRCed771242016-01-13 17:02:47 -08002759 back = ""
2760 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002761 ingress,
2762 egress,
2763 batchSize,
2764 offset,
2765 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002766 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002767 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002768 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002769 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002770 if getResponse:
2771 return response
2772
GlennRCed771242016-01-13 17:02:47 -08002773 # TODO: We should handle if there is failure in installation
2774 return main.TRUE
2775
Jon Hallc6793552016-01-19 14:18:37 -08002776 except AssertionError:
2777 main.log.exception( "" )
2778 return None
GlennRCed771242016-01-13 17:02:47 -08002779 except pexpect.TIMEOUT:
2780 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002781 return None
andrewonlab87852b02014-11-19 18:44:19 -05002782 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002783 main.log.error( self.name + ": EOF exception found" )
2784 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002785 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002786 except TypeError:
2787 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002788 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002789 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002790 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002791 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002792
YPZhangebf9eb52016-05-12 15:20:24 -07002793 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002794 """
2795 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002796 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002797 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002798 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002799 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002800 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002801
YPZhangb5d3f832016-01-23 22:54:26 -08002802 try:
YPZhange3109a72016-02-02 11:25:37 -08002803 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002804 cmd = "flows -c added"
2805 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2806 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002807 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002808 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002809 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002810 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002811 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002812 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002813 return None
2814 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002815
You Wangd3097f72018-12-12 11:56:03 -08002816 except IndexError:
2817 main.log.exception( "{}: Object not as expected!".format( self.name ) )
2818 main.log.debug( "rawFlows: {}".format( rawFlows ) )
2819 return None
You Wangd3cb2ce2016-05-16 14:01:24 -07002820 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002821 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002822 return None
2823 except pexpect.EOF:
2824 main.log.error( self.name + ": EOF exception found" )
2825 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002826 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002827 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002828 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002829 except pexpect.TIMEOUT:
2830 main.log.error( self.name + ": ONOS timeout" )
2831 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002832 except Exception:
2833 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002834 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002835 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002836 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002837
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002838 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002839 """
2840 Description:
2841 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002842 Optional:
2843 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002844 Return:
2845 The number of intents
2846 """
2847 try:
2848 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002849 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002850 if response is None:
2851 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002852 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002853 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002854 except ( TypeError, ValueError ):
2855 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002856 return None
2857 except pexpect.EOF:
2858 main.log.error( self.name + ": EOF exception found" )
2859 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002860 if noExit:
2861 return -1
2862 else:
Devin Lim44075962017-08-11 10:56:37 -07002863 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002864 except Exception:
2865 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002866 if noExit:
2867 return -1
2868 else:
Devin Lim44075962017-08-11 10:56:37 -07002869 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002870
kelvin-onlabd3b64892015-01-20 13:26:24 -08002871 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002872 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002873 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002874 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002875 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002876 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002877 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002878 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002879 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002880 cmdStr += " -j"
2881 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002882 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002883 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002884 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002885 except AssertionError:
2886 main.log.exception( "" )
2887 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002888 except TypeError:
2889 main.log.exception( self.name + ": Object not as expected" )
2890 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002891 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002892 main.log.error( self.name + ": EOF exception found" )
2893 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002894 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002895 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002896 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002897 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002898
kelvin-onlabd3b64892015-01-20 13:26:24 -08002899 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002900 """
2901 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002902 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002903 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002904 """
andrewonlab867212a2014-10-22 20:13:38 -04002905 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002906 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002907 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002908 cmdStr += " -j"
2909 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002910 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002911 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002912 if handle:
2913 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002914 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002915 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002916 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002917 else:
2918 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002919 except AssertionError:
2920 main.log.exception( "" )
2921 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002922 except TypeError:
2923 main.log.exception( self.name + ": Object not as expected" )
2924 return None
andrewonlab867212a2014-10-22 20:13:38 -04002925 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002926 main.log.error( self.name + ": EOF exception found" )
2927 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002928 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002929 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002930 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002931 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002932
kelvin8ec71442015-01-15 16:57:00 -08002933 # Wrapper functions ****************
2934 # Wrapper functions use existing driver
2935 # functions and extends their use case.
2936 # For example, we may use the output of
2937 # a normal driver function, and parse it
2938 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002939
kelvin-onlabd3b64892015-01-20 13:26:24 -08002940 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002941 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002942 Description:
2943 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002944 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002945 try:
kelvin8ec71442015-01-15 16:57:00 -08002946 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002947 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002948 if intentsStr is None:
2949 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002950 # Convert to a dictionary
2951 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002952 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002953 for intent in intents:
2954 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002955 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002956 except TypeError:
2957 main.log.exception( self.name + ": Object not as expected" )
2958 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002959 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002960 main.log.error( self.name + ": EOF exception found" )
2961 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002962 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002963 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002964 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002965 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002966
You Wang3c276252016-09-21 15:21:36 -07002967 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002968 """
2969 Determine the number of flow rules for the given device id that are
2970 in the added state
You Wang3c276252016-09-21 15:21:36 -07002971 Params:
2972 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002973 """
2974 try:
You Wang3c276252016-09-21 15:21:36 -07002975 if core:
2976 cmdStr = "flows any " + str( deviceId ) + " | " +\
2977 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2978 else:
2979 cmdStr = "flows any " + str( deviceId ) + " | " +\
2980 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08002981 handle = self.lineCount( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002982 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002983 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002984 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002985 except AssertionError:
2986 main.log.exception( "" )
2987 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002988 except pexpect.EOF:
2989 main.log.error( self.name + ": EOF exception found" )
2990 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002991 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002992 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002993 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002994 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002995
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002996 def groupAddedCount( self, deviceId, core=False ):
2997 """
2998 Determine the number of group rules for the given device id that are
2999 in the added state
3000 Params:
3001 core: if True, only return the number of core groups added
3002 """
3003 try:
3004 if core:
3005 cmdStr = "groups any " + str( deviceId ) + " | " +\
3006 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
3007 else:
3008 cmdStr = "groups any " + str( deviceId ) + " | " +\
3009 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003010 handle = self.lineCount( cmdStr )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003011 assert handle is not None, "Error in sendline"
3012 assert "Command not found:" not in handle, handle
3013 return handle
3014 except AssertionError:
3015 main.log.exception( "" )
3016 return None
3017 except pexpect.EOF:
3018 main.log.error( self.name + ": EOF exception found" )
3019 main.log.error( self.name + ": " + self.handle.before )
3020 main.cleanAndExit()
3021 except Exception:
3022 main.log.exception( self.name + ": Uncaught exception!" )
3023 main.cleanAndExit()
3024
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003025 def addStaticRoute( self, subnet, intf):
3026 """
3027 Adds a static route to onos.
3028 Params:
3029 subnet: The subnet reaching through this route
3030 intf: The interface this route is reachable through
3031 """
3032 try:
3033 cmdStr = "route-add " + subnet + " " + intf
3034 handle = self.sendline( cmdStr )
3035 assert handle is not None, "Error in sendline"
3036 assert "Command not found:" not in handle, handle
3037 return handle
3038 except AssertionError:
3039 main.log.exception( "" )
3040 return None
3041 except pexpect.EOF:
3042 main.log.error( self.name + ": EOF exception found" )
3043 main.log.error( self.name + ": " + self.handle.before )
3044 main.cleanAndExit()
3045 except Exception:
3046 main.log.exception( self.name + ": Uncaught exception!" )
3047 main.cleanAndExit()
3048
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003049 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
3050 """
3051 Description:
3052 Check whether the number of groups for the given device id that
3053 are in ADDED state is bigger than minGroupCount.
3054 Required:
3055 * deviceId: device id to check the number of added group rules
3056 Optional:
3057 * minGroupCount: the number of groups to compare
3058 * core: if True, only check the number of core groups added
3059 * comparison: if 0, compare with greater than minFlowCount
3060 * if 1, compare with equal to minFlowCount
3061 Return:
3062 Returns the number of groups if it is bigger than minGroupCount,
3063 returns main.FALSE otherwise.
3064 """
3065 count = self.groupAddedCount( deviceId, core )
3066 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003067 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003068 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
3069
You Wangc02f3be2018-05-18 12:14:23 -07003070 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003071 """
3072 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07003073 deviceId: Id of the device from which we retrieve groups
3074 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003075 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003076 try:
You Wangc02f3be2018-05-18 12:14:23 -07003077 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
3078 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003079 assert handle is not None, "Error in sendline"
3080 assert "Command not found:" not in handle, handle
3081 return handle
3082 except AssertionError:
3083 main.log.exception( "" )
3084 return None
3085 except TypeError:
3086 main.log.exception( self.name + ": Object not as expected" )
3087 return None
3088 except pexpect.EOF:
3089 main.log.error( self.name + ": EOF exception found" )
3090 main.log.error( self.name + ": " + self.handle.before )
3091 main.cleanAndExit()
3092 except Exception:
3093 main.log.exception( self.name + ": Uncaught exception!" )
3094 main.cleanAndExit()
3095
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003096 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003097 """
3098 Description:
3099 Check whether the number of flow rules for the given device id that
3100 are in ADDED state is bigger than minFlowCount.
3101 Required:
3102 * deviceId: device id to check the number of added flow rules
3103 Optional:
3104 * minFlowCount: the number of flow rules to compare
3105 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003106 * comparison: if 0, compare with greater than minFlowCount
3107 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003108 Return:
3109 Returns the number of flow rules if it is bigger than minFlowCount,
3110 returns main.FALSE otherwise.
3111 """
3112 count = self.flowAddedCount( deviceId, core )
3113 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003114 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003115 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003116
kelvin-onlabd3b64892015-01-20 13:26:24 -08003117 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003118 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003119 Use 'devices' function to obtain list of all devices
3120 and parse the result to obtain a list of all device
3121 id's. Returns this list. Returns empty list if no
3122 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003123 List is ordered sequentially
3124
andrewonlab3e15ead2014-10-15 14:21:34 -04003125 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003126 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003127 the ids. By obtaining the list of device ids on the fly,
3128 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003129 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003130 try:
kelvin8ec71442015-01-15 16:57:00 -08003131 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003132 devicesStr = self.devices( jsonFormat=False )
3133 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003134
kelvin-onlabd3b64892015-01-20 13:26:24 -08003135 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003136 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003137 return idList
kelvin8ec71442015-01-15 16:57:00 -08003138
3139 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003140 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003141 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003142 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003143 # Split list further into arguments before and after string
3144 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003145 # append to idList
3146 for arg in tempList:
3147 idList.append( arg.split( "id=" )[ 1 ] )
3148 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003149
Jon Halld4d4b372015-01-28 16:02:41 -08003150 except TypeError:
3151 main.log.exception( self.name + ": Object not as expected" )
3152 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003153 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003154 main.log.error( self.name + ": EOF exception found" )
3155 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003156 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003157 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003158 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003159 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003160
kelvin-onlabd3b64892015-01-20 13:26:24 -08003161 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003162 """
andrewonlab7c211572014-10-15 16:45:20 -04003163 Uses 'nodes' function to obtain list of all nodes
3164 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003165 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003166 Returns:
3167 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003168 """
andrewonlab7c211572014-10-15 16:45:20 -04003169 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003170 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003171 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003172 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003173 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003174 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003175 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003176 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003177 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003178 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003179 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003180 except ( TypeError, ValueError ):
3181 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003182 return None
andrewonlab7c211572014-10-15 16:45:20 -04003183 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003184 main.log.error( self.name + ": EOF exception found" )
3185 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003186 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003187 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003188 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003189 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003190
kelvin-onlabd3b64892015-01-20 13:26:24 -08003191 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003192 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003193 Return the first device from the devices api whose 'id' contains 'dpid'
3194 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003195 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003196 try:
kelvin8ec71442015-01-15 16:57:00 -08003197 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003198 return None
3199 else:
kelvin8ec71442015-01-15 16:57:00 -08003200 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003201 rawDevices = self.devices()
3202 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003203 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003204 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003205 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3206 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003207 return device
3208 return None
Jon Hallc6793552016-01-19 14:18:37 -08003209 except ( TypeError, ValueError ):
3210 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003211 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003212 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003213 main.log.error( self.name + ": EOF exception found" )
3214 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003215 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003216 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003217 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003218 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003219
You Wang24139872016-05-03 11:48:47 -07003220 def getTopology( self, topologyOutput ):
3221 """
3222 Definition:
3223 Loads a json topology output
3224 Return:
3225 topology = current ONOS topology
3226 """
3227 import json
3228 try:
3229 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003230 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003231 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003232 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003233 except ( TypeError, ValueError ):
3234 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3235 return None
You Wang24139872016-05-03 11:48:47 -07003236 except pexpect.EOF:
3237 main.log.error( self.name + ": EOF exception found" )
3238 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003239 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003240 except Exception:
3241 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003242 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003243
Pier6a0c4de2018-03-18 16:01:30 -07003244 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003245 """
Jon Hallefbd9792015-03-05 16:11:36 -08003246 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003247 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003248 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003249
Flavio Castro82ee2f62016-06-07 15:04:12 -07003250 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003251 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003252 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003253 logLevel = level to log to.
3254 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003255
Jon Hallefbd9792015-03-05 16:11:36 -08003256 Returns: main.TRUE if the number of switches and links are correct,
3257 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003258 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003259 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003260 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003261 try:
You Wang13310252016-07-31 10:56:14 -07003262 summary = self.summary()
3263 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003264 except ( TypeError, ValueError ):
3265 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3266 return main.ERROR
3267 try:
3268 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003269 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003270 return main.ERROR
3271 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003272 # Is the number of switches is what we expected
3273 devices = topology.get( 'devices', False )
3274 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003275 nodes = summary.get( 'nodes', False )
3276 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003277 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003278 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003279 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003280 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003281 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3282 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003283 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003284 output = output + "The number of links and switches match "\
3285 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003286 result = main.TRUE
3287 else:
You Wang24139872016-05-03 11:48:47 -07003288 output = output + \
3289 "The number of links and switches does not match " + \
3290 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003291 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003292 output = output + "\n ONOS sees %i devices" % int( devices )
3293 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003294 if int( numolink ) > 0:
3295 output = output + "and %i links " % int( links )
3296 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003297 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003298 output = output + "and %i controllers " % int( nodes )
3299 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003300 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003301 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003302 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003303 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003304 else:
You Wang24139872016-05-03 11:48:47 -07003305 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003306 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003307 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003308 main.log.error( self.name + ": EOF exception found" )
3309 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003310 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003311 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003312 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003313 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003314
kelvin-onlabd3b64892015-01-20 13:26:24 -08003315 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003316 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003317 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003318 deviceId must be the id of a device as seen in the onos devices command
3319 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003320 role must be either master, standby, or none
3321
Jon Halle3f39ff2015-01-13 11:50:53 -08003322 Returns:
3323 main.TRUE or main.FALSE based on argument verification and
3324 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003325 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003326 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003327 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003328 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003329 cmdStr = "device-role " +\
3330 str( deviceId ) + " " +\
3331 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003332 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003333 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003334 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003335 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003336 if re.search( "Error", handle ):
3337 # end color output to escape any colours
3338 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003339 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003340 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003341 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003342 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003343 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003344 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003345 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003346 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003347 except AssertionError:
3348 main.log.exception( "" )
3349 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003350 except TypeError:
3351 main.log.exception( self.name + ": Object not as expected" )
3352 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003353 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003354 main.log.error( self.name + ": EOF exception found" )
3355 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003356 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003357 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003358 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003359 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003360
kelvin-onlabd3b64892015-01-20 13:26:24 -08003361 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003362 """
Jon Hall0dd09952018-04-19 09:59:11 -07003363 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003364 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003365 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003366 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003367 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003368 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003369 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003370 cmdStr += " -j"
3371 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003372 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003373 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003374 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003375 except AssertionError:
3376 main.log.exception( "" )
3377 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003378 except TypeError:
3379 main.log.exception( self.name + ": Object not as expected" )
3380 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003381 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003382 main.log.error( self.name + ": EOF exception found" )
3383 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003384 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003385 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003386 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003387 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003388
kelvin-onlabd3b64892015-01-20 13:26:24 -08003389 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003390 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003391 CLI command to get the current leader for the Election test application
3392 NOTE: Requires installation of the onos-app-election feature
3393 Returns: Node IP of the leader if one exists
3394 None if none exists
3395 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003396 """
Jon Hall94fd0472014-12-08 11:52:42 -08003397 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003398 cmdStr = "election-test-leader"
3399 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003400 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003401 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003402 # Leader
3403 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003404 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003405 nodeSearch = re.search( leaderPattern, response )
3406 if nodeSearch:
3407 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003408 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003409 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003410 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003411 # no leader
3412 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003413 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003414 nullSearch = re.search( nullPattern, response )
3415 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003416 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003417 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003418 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003419 # error
Jon Hall0e240372018-05-02 11:21:57 -07003420 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003421 ": " + "unexpected response" )
3422 main.log.error( repr( response ) )
3423 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003424 except AssertionError:
3425 main.log.exception( "" )
3426 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003427 except TypeError:
3428 main.log.exception( self.name + ": Object not as expected" )
3429 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003430 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003431 main.log.error( self.name + ": EOF exception found" )
3432 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003433 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003434 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003435 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003436 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003437
kelvin-onlabd3b64892015-01-20 13:26:24 -08003438 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003439 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003440 CLI command to run for leadership of the Election test application.
3441 NOTE: Requires installation of the onos-app-election feature
3442 Returns: Main.TRUE on success
3443 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003444 """
Jon Hall94fd0472014-12-08 11:52:42 -08003445 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003446 cmdStr = "election-test-run"
3447 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003448 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003449 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003450 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003451 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003452 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003453 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003454 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003455 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003456 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003457 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003458 # error
Jon Hall0e240372018-05-02 11:21:57 -07003459 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003460 ": " + "unexpected response" )
3461 main.log.error( repr( response ) )
3462 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003463 except AssertionError:
3464 main.log.exception( "" )
3465 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003466 except TypeError:
3467 main.log.exception( self.name + ": Object not as expected" )
3468 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003469 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003470 main.log.error( self.name + ": EOF exception found" )
3471 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003472 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003473 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003474 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003475 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003476
kelvin-onlabd3b64892015-01-20 13:26:24 -08003477 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003478 """
Jon Hall94fd0472014-12-08 11:52:42 -08003479 * CLI command to withdraw the local node from leadership election for
3480 * the Election test application.
3481 #NOTE: Requires installation of the onos-app-election feature
3482 Returns: Main.TRUE on success
3483 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003484 """
Jon Hall94fd0472014-12-08 11:52:42 -08003485 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003486 cmdStr = "election-test-withdraw"
3487 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003488 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003489 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003490 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003491 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003492 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003493 if re.search( successPattern, response ):
3494 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003495 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003496 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003497 # error
Jon Hall0e240372018-05-02 11:21:57 -07003498 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003499 self.name + ": " + "unexpected response" )
3500 main.log.error( repr( response ) )
3501 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003502 except AssertionError:
3503 main.log.exception( "" )
3504 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003505 except TypeError:
3506 main.log.exception( self.name + ": Object not as expected" )
3507 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003508 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003509 main.log.error( self.name + ": EOF exception found" )
3510 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003511 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003512 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003513 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003514 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003515
kelvin8ec71442015-01-15 16:57:00 -08003516 def getDevicePortsEnabledCount( self, dpid ):
3517 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003518 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003519 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003520 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003521 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003522 cmdStr = "onos:ports -e " + dpid + " | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003523 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003524 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003525 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003526 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003527 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003528 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003529 return output
Jon Hallc6793552016-01-19 14:18:37 -08003530 except AssertionError:
3531 main.log.exception( "" )
3532 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003533 except TypeError:
3534 main.log.exception( self.name + ": Object not as expected" )
3535 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003536 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003537 main.log.error( self.name + ": EOF exception found" )
3538 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003539 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003540 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003541 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003542 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003543
kelvin8ec71442015-01-15 16:57:00 -08003544 def getDeviceLinksActiveCount( self, dpid ):
3545 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003546 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003547 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003548 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003549 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003550 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003551 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003552 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003553 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003554 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003555 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003556 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003557 return output
Jon Hallc6793552016-01-19 14:18:37 -08003558 except AssertionError:
3559 main.log.exception( "" )
3560 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003561 except TypeError:
3562 main.log.exception( self.name + ": Object not as expected" )
3563 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003564 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003565 main.log.error( self.name + ": EOF exception found" )
3566 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003567 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003568 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003569 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003570 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003571
kelvin8ec71442015-01-15 16:57:00 -08003572 def getAllIntentIds( self ):
3573 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003574 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003575 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003576 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003577 cmdStr = "onos:intents | grep id="
3578 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003579 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003580 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003581 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003582 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003583 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003584 return output
Jon Hallc6793552016-01-19 14:18:37 -08003585 except AssertionError:
3586 main.log.exception( "" )
3587 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003588 except TypeError:
3589 main.log.exception( self.name + ": Object not as expected" )
3590 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003591 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003592 main.log.error( self.name + ": EOF exception found" )
3593 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003594 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003595 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003596 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003597 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003598
Jon Hall73509952015-02-24 16:42:56 -08003599 def intentSummary( self ):
3600 """
Jon Hallefbd9792015-03-05 16:11:36 -08003601 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003602 """
3603 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003604 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003605 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003606 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003607 states.append( intent.get( 'state', None ) )
3608 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003609 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003610 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003611 except ( TypeError, ValueError ):
3612 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003613 return None
3614 except pexpect.EOF:
3615 main.log.error( self.name + ": EOF exception found" )
3616 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003617 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003618 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003619 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003620 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003621
Jon Hall61282e32015-03-19 11:34:11 -07003622 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003623 """
3624 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003625 Optional argument:
3626 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003627 """
Jon Hall63604932015-02-26 17:09:50 -08003628 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003629 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003630 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003631 cmdStr += " -j"
3632 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003633 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003634 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003635 return output
Jon Hallc6793552016-01-19 14:18:37 -08003636 except AssertionError:
3637 main.log.exception( "" )
3638 return None
Jon Hall63604932015-02-26 17:09:50 -08003639 except TypeError:
3640 main.log.exception( self.name + ": Object not as expected" )
3641 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003642 except pexpect.EOF:
3643 main.log.error( self.name + ": EOF exception found" )
3644 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003645 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003646 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003647 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003648 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003649
acsmarsa4a4d1e2015-07-10 16:01:24 -07003650 def leaderCandidates( self, jsonFormat=True ):
3651 """
3652 Returns the output of the leaders -c command.
3653 Optional argument:
3654 * jsonFormat - boolean indicating if you want output in json
3655 """
3656 try:
3657 cmdStr = "onos:leaders -c"
3658 if jsonFormat:
3659 cmdStr += " -j"
3660 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003661 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003662 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003663 return output
Jon Hallc6793552016-01-19 14:18:37 -08003664 except AssertionError:
3665 main.log.exception( "" )
3666 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003667 except TypeError:
3668 main.log.exception( self.name + ": Object not as expected" )
3669 return None
3670 except pexpect.EOF:
3671 main.log.error( self.name + ": EOF exception found" )
3672 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003673 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003674 except Exception:
3675 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003676 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003677
Jon Hallc6793552016-01-19 14:18:37 -08003678 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003679 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003680 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003681 topic parameter and an empty list if the topic doesn't exist
3682 If no leader is elected leader in the returned list will be "none"
3683 Returns None if there is a type error processing the json object
3684 """
3685 try:
Jon Hall6e709752016-02-01 13:38:46 -08003686 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003687 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003688 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003689 assert "Command not found:" not in rawOutput, rawOutput
3690 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003691 results = []
3692 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003693 if dict[ "topic" ] == topic:
3694 leader = dict[ "leader" ]
3695 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003696 results.append( leader )
3697 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003698 return results
Jon Hallc6793552016-01-19 14:18:37 -08003699 except AssertionError:
3700 main.log.exception( "" )
3701 return None
3702 except ( TypeError, ValueError ):
3703 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003704 return None
3705 except pexpect.EOF:
3706 main.log.error( self.name + ": EOF exception found" )
3707 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003708 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003709 except Exception:
3710 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003711 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003712
Jon Hall61282e32015-03-19 11:34:11 -07003713 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003714 """
3715 Returns the output of the intent Pending map.
3716 """
Jon Hall63604932015-02-26 17:09:50 -08003717 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003718 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003719 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003720 cmdStr += " -j"
3721 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003722 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003723 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003724 return output
Jon Hallc6793552016-01-19 14:18:37 -08003725 except AssertionError:
3726 main.log.exception( "" )
3727 return None
Jon Hall63604932015-02-26 17:09:50 -08003728 except TypeError:
3729 main.log.exception( self.name + ": Object not as expected" )
3730 return None
3731 except pexpect.EOF:
3732 main.log.error( self.name + ": EOF exception found" )
3733 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003734 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003735 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003736 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003737 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003738
Jon Hall2c8959e2016-12-16 12:17:34 -08003739 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003740 """
3741 Returns the output of the raft partitions command for ONOS.
3742 """
Jon Hall61282e32015-03-19 11:34:11 -07003743 # Sample JSON
3744 # {
3745 # "leader": "tcp://10.128.30.11:7238",
3746 # "members": [
3747 # "tcp://10.128.30.11:7238",
3748 # "tcp://10.128.30.17:7238",
3749 # "tcp://10.128.30.13:7238",
3750 # ],
3751 # "name": "p1",
3752 # "term": 3
3753 # },
Jon Hall63604932015-02-26 17:09:50 -08003754 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003755 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003756 if candidates:
3757 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003758 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003759 cmdStr += " -j"
3760 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003761 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003762 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003763 return output
Jon Hallc6793552016-01-19 14:18:37 -08003764 except AssertionError:
3765 main.log.exception( "" )
3766 return None
Jon Hall63604932015-02-26 17:09:50 -08003767 except TypeError:
3768 main.log.exception( self.name + ": Object not as expected" )
3769 return None
3770 except pexpect.EOF:
3771 main.log.error( self.name + ": EOF exception found" )
3772 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003773 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003774 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003775 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003776 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003777
Jon Halle9f909e2016-09-23 10:43:12 -07003778 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003779 """
3780 Returns the output of the apps command for ONOS. This command lists
3781 information about installed ONOS applications
3782 """
3783 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003784 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003785 # "description":"ONOS OpenFlow protocol southbound providers",
3786 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003787 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003788 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003789 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003790 if summary:
3791 cmdStr += " -s"
3792 if active:
3793 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003794 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003795 cmdStr += " -j"
3796 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003797 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003798 assert "Command not found:" not in output, output
3799 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003800 return output
Jon Hallbe379602015-03-24 13:39:32 -07003801 # FIXME: look at specific exceptions/Errors
3802 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003803 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003804 return None
3805 except TypeError:
3806 main.log.exception( self.name + ": Object not as expected" )
3807 return None
3808 except pexpect.EOF:
3809 main.log.error( self.name + ": EOF exception found" )
3810 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003811 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003812 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003813 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003814 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003815
You Wangcdc51fe2018-08-12 17:14:56 -07003816 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003817 """
3818 Uses the onos:apps cli command to return the status of an application.
3819 Returns:
3820 "ACTIVE" - If app is installed and activated
3821 "INSTALLED" - If app is installed and deactivated
3822 "UNINSTALLED" - If app is not installed
3823 None - on error
3824 """
Jon Hall146f1522015-03-24 15:33:24 -07003825 try:
3826 if not isinstance( appName, types.StringType ):
3827 main.log.error( self.name + ".appStatus(): appName must be" +
3828 " a string" )
3829 return None
3830 output = self.apps( jsonFormat=True )
3831 appsJson = json.loads( output )
3832 state = None
3833 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003834 if appName == app.get( 'name' ):
3835 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003836 break
3837 if state == "ACTIVE" or state == "INSTALLED":
3838 return state
3839 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003840 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003841 return "UNINSTALLED"
3842 elif state:
3843 main.log.error( "Unexpected state from 'onos:apps': " +
3844 str( state ) )
3845 return state
Jon Hallc6793552016-01-19 14:18:37 -08003846 except ( TypeError, ValueError ):
3847 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003848 return None
3849 except pexpect.EOF:
3850 main.log.error( self.name + ": EOF exception found" )
3851 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003852 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003853 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003854 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003855 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003856
Jon Hallbe379602015-03-24 13:39:32 -07003857 def app( self, appName, option ):
3858 """
3859 Interacts with the app command for ONOS. This command manages
3860 application inventory.
3861 """
Jon Hallbe379602015-03-24 13:39:32 -07003862 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003863 # Validate argument types
3864 valid = True
3865 if not isinstance( appName, types.StringType ):
3866 main.log.error( self.name + ".app(): appName must be a " +
3867 "string" )
3868 valid = False
3869 if not isinstance( option, types.StringType ):
3870 main.log.error( self.name + ".app(): option must be a string" )
3871 valid = False
3872 if not valid:
3873 return main.FALSE
3874 # Validate Option
3875 option = option.lower()
3876 # NOTE: Install may become a valid option
3877 if option == "activate":
3878 pass
3879 elif option == "deactivate":
3880 pass
3881 elif option == "uninstall":
3882 pass
3883 else:
3884 # Invalid option
3885 main.log.error( "The ONOS app command argument only takes " +
3886 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003887 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003888 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003889 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003890 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003891 assert output is not None, "Error in sendline"
3892 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003893 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003894 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003895 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003896 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003897 elif "No such application" in output:
3898 main.log.error( "The application '" + appName +
3899 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003900 return main.FALSE
3901 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003902 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003903 str( output ) )
3904 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003905 elif "Unsupported command:" in output:
3906 main.log.error( "Incorrect command given to 'app': " +
3907 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003908 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003909 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003910 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003911 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003912 except AssertionError:
3913 main.log.exception( self.name + ": AssertionError exception found" )
3914 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003915 except TypeError:
3916 main.log.exception( self.name + ": Object not as expected" )
3917 return main.ERROR
3918 except pexpect.EOF:
3919 main.log.error( self.name + ": EOF exception found" )
3920 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003921 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003922 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003923 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003924 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003925
Jon Hallbd16b922015-03-26 17:53:15 -07003926 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003927 """
3928 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003929 appName is the hierarchical app name, not the feature name
3930 If check is True, method will check the status of the app after the
3931 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003932 Returns main.TRUE if the command was successfully sent
3933 main.FALSE if the cli responded with an error or given
3934 incorrect input
3935 """
3936 try:
3937 if not isinstance( appName, types.StringType ):
3938 main.log.error( self.name + ".activateApp(): appName must be" +
3939 " a string" )
3940 return main.FALSE
3941 status = self.appStatus( appName )
3942 if status == "INSTALLED":
3943 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003944 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003945 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003946 status = self.appStatus( appName )
3947 if status == "ACTIVE":
3948 return main.TRUE
3949 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003950 main.log.debug( "The state of application " +
3951 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003952 time.sleep( 1 )
3953 return main.FALSE
3954 else: # not 'check' or command didn't succeed
3955 return response
Jon Hall146f1522015-03-24 15:33:24 -07003956 elif status == "ACTIVE":
3957 return main.TRUE
3958 elif status == "UNINSTALLED":
3959 main.log.error( self.name + ": Tried to activate the " +
3960 "application '" + appName + "' which is not " +
3961 "installed." )
3962 else:
3963 main.log.error( "Unexpected return value from appStatus: " +
3964 str( status ) )
3965 return main.ERROR
3966 except TypeError:
3967 main.log.exception( self.name + ": Object not as expected" )
3968 return main.ERROR
3969 except pexpect.EOF:
3970 main.log.error( self.name + ": EOF exception found" )
3971 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003972 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003973 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003974 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003975 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003976
Jon Hallbd16b922015-03-26 17:53:15 -07003977 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003978 """
3979 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003980 appName is the hierarchical app name, not the feature name
3981 If check is True, method will check the status of the app after the
3982 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003983 Returns main.TRUE if the command was successfully sent
3984 main.FALSE if the cli responded with an error or given
3985 incorrect input
3986 """
3987 try:
3988 if not isinstance( appName, types.StringType ):
3989 main.log.error( self.name + ".deactivateApp(): appName must " +
3990 "be a string" )
3991 return main.FALSE
3992 status = self.appStatus( appName )
3993 if status == "INSTALLED":
3994 return main.TRUE
3995 elif status == "ACTIVE":
3996 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003997 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003998 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003999 status = self.appStatus( appName )
4000 if status == "INSTALLED":
4001 return main.TRUE
4002 else:
4003 time.sleep( 1 )
4004 return main.FALSE
4005 else: # not check or command didn't succeed
4006 return response
Jon Hall146f1522015-03-24 15:33:24 -07004007 elif status == "UNINSTALLED":
4008 main.log.warn( self.name + ": Tried to deactivate the " +
4009 "application '" + appName + "' which is not " +
4010 "installed." )
4011 return main.TRUE
4012 else:
4013 main.log.error( "Unexpected return value from appStatus: " +
4014 str( status ) )
4015 return main.ERROR
4016 except TypeError:
4017 main.log.exception( self.name + ": Object not as expected" )
4018 return main.ERROR
4019 except pexpect.EOF:
4020 main.log.error( self.name + ": EOF exception found" )
4021 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004022 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004023 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004024 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004025 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004026
Jon Hallbd16b922015-03-26 17:53:15 -07004027 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004028 """
4029 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004030 appName is the hierarchical app name, not the feature name
4031 If check is True, method will check the status of the app after the
4032 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004033 Returns main.TRUE if the command was successfully sent
4034 main.FALSE if the cli responded with an error or given
4035 incorrect input
4036 """
4037 # TODO: check with Thomas about the state machine for apps
4038 try:
4039 if not isinstance( appName, types.StringType ):
4040 main.log.error( self.name + ".uninstallApp(): appName must " +
4041 "be a string" )
4042 return main.FALSE
4043 status = self.appStatus( appName )
4044 if status == "INSTALLED":
4045 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004046 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004047 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004048 status = self.appStatus( appName )
4049 if status == "UNINSTALLED":
4050 return main.TRUE
4051 else:
4052 time.sleep( 1 )
4053 return main.FALSE
4054 else: # not check or command didn't succeed
4055 return response
Jon Hall146f1522015-03-24 15:33:24 -07004056 elif status == "ACTIVE":
4057 main.log.warn( self.name + ": Tried to uninstall the " +
4058 "application '" + appName + "' which is " +
4059 "currently active." )
4060 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004061 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004062 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004063 status = self.appStatus( appName )
4064 if status == "UNINSTALLED":
4065 return main.TRUE
4066 else:
4067 time.sleep( 1 )
4068 return main.FALSE
4069 else: # not check or command didn't succeed
4070 return response
Jon Hall146f1522015-03-24 15:33:24 -07004071 elif status == "UNINSTALLED":
4072 return main.TRUE
4073 else:
4074 main.log.error( "Unexpected return value from appStatus: " +
4075 str( status ) )
4076 return main.ERROR
4077 except TypeError:
4078 main.log.exception( self.name + ": Object not as expected" )
4079 return main.ERROR
4080 except pexpect.EOF:
4081 main.log.error( self.name + ": EOF exception found" )
4082 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004083 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004084 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004085 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004086 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004087
4088 def appIDs( self, jsonFormat=True ):
4089 """
4090 Show the mappings between app id and app names given by the 'app-ids'
4091 cli command
4092 """
4093 try:
4094 cmdStr = "app-ids"
4095 if jsonFormat:
4096 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004097 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004098 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004099 assert "Command not found:" not in output, output
4100 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004101 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004102 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004103 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004104 return None
4105 except TypeError:
4106 main.log.exception( self.name + ": Object not as expected" )
4107 return None
4108 except pexpect.EOF:
4109 main.log.error( self.name + ": EOF exception found" )
4110 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004111 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004112 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004113 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004114 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004115
4116 def appToIDCheck( self ):
4117 """
4118 This method will check that each application's ID listed in 'apps' is
4119 the same as the ID listed in 'app-ids'. The check will also check that
4120 there are no duplicate IDs issued. Note that an app ID should be
4121 a globaly unique numerical identifier for app/app-like features. Once
4122 an ID is registered, the ID is never freed up so that if an app is
4123 reinstalled it will have the same ID.
4124
4125 Returns: main.TRUE if the check passes and
4126 main.FALSE if the check fails or
4127 main.ERROR if there is some error in processing the test
4128 """
4129 try:
Jon Hall0e240372018-05-02 11:21:57 -07004130 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004131 rawJson = self.appIDs( jsonFormat=True )
4132 if rawJson:
4133 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004134 else:
Jon Hall0e240372018-05-02 11:21:57 -07004135 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4136 return main.FALSE
4137
4138 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004139 rawJson = self.apps( jsonFormat=True )
4140 if rawJson:
4141 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004142 else:
Jon Hallc6793552016-01-19 14:18:37 -08004143 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004144 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004145
Jon Hallbd16b922015-03-26 17:53:15 -07004146 result = main.TRUE
4147 for app in apps:
4148 appID = app.get( 'id' )
4149 if appID is None:
4150 main.log.error( "Error parsing app: " + str( app ) )
4151 result = main.FALSE
4152 appName = app.get( 'name' )
4153 if appName is None:
4154 main.log.error( "Error parsing app: " + str( app ) )
4155 result = main.FALSE
4156 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004157 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004158 if not current: # if ids doesn't have this id
4159 result = main.FALSE
4160 main.log.error( "'app-ids' does not have the ID for " +
4161 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004162 main.log.debug( "apps command returned: " + str( app ) +
4163 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004164 elif len( current ) > 1:
4165 # there is more than one app with this ID
4166 result = main.FALSE
4167 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004168 elif not current[ 0 ][ 'name' ] == appName:
4169 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004170 result = main.FALSE
4171 main.log.error( "'app-ids' has " + str( currentName ) +
4172 " registered under id:" + str( appID ) +
4173 " but 'apps' has " + str( appName ) )
4174 else:
4175 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004176
Jon Hallbd16b922015-03-26 17:53:15 -07004177 # now make sure that app-ids has no duplicates
4178 idsList = []
4179 namesList = []
4180 for item in ids:
4181 idsList.append( item[ 'id' ] )
4182 namesList.append( item[ 'name' ] )
4183 if len( idsList ) != len( set( idsList ) ) or\
4184 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004185 main.log.error( "'app-ids' has some duplicate entries: \n"
4186 + json.dumps( ids,
4187 sort_keys=True,
4188 indent=4,
4189 separators=( ',', ': ' ) ) )
4190 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004191 return result
Jon Hallc6793552016-01-19 14:18:37 -08004192 except ( TypeError, ValueError ):
4193 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004194 return main.ERROR
4195 except pexpect.EOF:
4196 main.log.error( self.name + ": EOF exception found" )
4197 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004198 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004199 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004200 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004201 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004202
Jon Hallfb760a02015-04-13 15:35:03 -07004203 def getCfg( self, component=None, propName=None, short=False,
4204 jsonFormat=True ):
4205 """
4206 Get configuration settings from onos cli
4207 Optional arguments:
4208 component - Optionally only list configurations for a specific
4209 component. If None, all components with configurations
4210 are displayed. Case Sensitive string.
4211 propName - If component is specified, propName option will show
4212 only this specific configuration from that component.
4213 Case Sensitive string.
4214 jsonFormat - Returns output as json. Note that this will override
4215 the short option
4216 short - Short, less verbose, version of configurations.
4217 This is overridden by the json option
4218 returns:
4219 Output from cli as a string or None on error
4220 """
4221 try:
4222 baseStr = "cfg"
4223 cmdStr = " get"
4224 componentStr = ""
4225 if component:
4226 componentStr += " " + component
4227 if propName:
4228 componentStr += " " + propName
4229 if jsonFormat:
4230 baseStr += " -j"
4231 elif short:
4232 baseStr += " -s"
4233 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004234 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004235 assert "Command not found:" not in output, output
4236 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004237 return output
4238 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004239 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004240 return None
4241 except TypeError:
4242 main.log.exception( self.name + ": Object not as expected" )
4243 return None
4244 except pexpect.EOF:
4245 main.log.error( self.name + ": EOF exception found" )
4246 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004247 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004248 except Exception:
4249 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004250 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004251
4252 def setCfg( self, component, propName, value=None, check=True ):
4253 """
4254 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004255 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004256 component - The case sensitive name of the component whose
4257 property is to be set
4258 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004259 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004260 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004261 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004262 check - Boolean, Check whether the option was successfully set this
4263 only applies when a value is given.
4264 returns:
4265 main.TRUE on success or main.FALSE on failure. If check is False,
4266 will return main.TRUE unless there is an error
4267 """
4268 try:
4269 baseStr = "cfg"
4270 cmdStr = " set " + str( component ) + " " + str( propName )
4271 if value is not None:
4272 cmdStr += " " + str( value )
4273 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004274 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004275 assert "Command not found:" not in output, output
4276 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004277 if value and check:
4278 results = self.getCfg( component=str( component ),
4279 propName=str( propName ),
4280 jsonFormat=True )
4281 # Check if current value is what we just set
4282 try:
4283 jsonOutput = json.loads( results )
4284 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004285 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004286 main.log.exception( "Error parsing cfg output" )
4287 main.log.error( "output:" + repr( results ) )
4288 return main.FALSE
4289 if current == str( value ):
4290 return main.TRUE
4291 return main.FALSE
4292 return main.TRUE
4293 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004294 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004295 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004296 except ( TypeError, ValueError ):
4297 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004298 return main.FALSE
4299 except pexpect.EOF:
4300 main.log.error( self.name + ": EOF exception found" )
4301 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004302 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004303 except Exception:
4304 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004305 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004306
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004307 def distPrimitivesSend( self, cmd ):
4308 """
4309 Function to handle sending cli commands for the distributed primitives test app
4310
4311 This command will catch some exceptions and retry the command on some
4312 specific store exceptions.
4313
4314 Required arguments:
4315 cmd - The command to send to the cli
4316 returns:
4317 string containing the cli output
4318 None on Error
4319 """
4320 try:
4321 output = self.sendline( cmd )
4322 try:
4323 assert output is not None, "Error in sendline"
4324 # TODO: Maybe make this less hardcoded
4325 # ConsistentMap Exceptions
4326 assert "org.onosproject.store.service" not in output
4327 # Node not leader
4328 assert "java.lang.IllegalStateException" not in output
4329 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004330 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004331 "command: " + str( output ) )
4332 retryTime = 30 # Conservative time, given by Madan
4333 main.log.info( "Waiting " + str( retryTime ) +
4334 "seconds before retrying." )
4335 time.sleep( retryTime ) # Due to change in mastership
4336 output = self.sendline( cmd )
4337 assert output is not None, "Error in sendline"
4338 assert "Command not found:" not in output, output
4339 assert "Error executing command" not in output, output
4340 main.log.info( self.name + ": " + output )
4341 return output
4342 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004343 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004344 return None
4345 except TypeError:
4346 main.log.exception( self.name + ": Object not as expected" )
4347 return None
4348 except pexpect.EOF:
4349 main.log.error( self.name + ": EOF exception found" )
4350 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004351 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004352 except Exception:
4353 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004354 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004355
Jon Hall390696c2015-05-05 17:13:41 -07004356 def setTestAdd( self, setName, values ):
4357 """
4358 CLI command to add elements to a distributed set.
4359 Arguments:
4360 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004361 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004362 Example usages:
4363 setTestAdd( "set1", "a b c" )
4364 setTestAdd( "set2", "1" )
4365 returns:
4366 main.TRUE on success OR
4367 main.FALSE if elements were already in the set OR
4368 main.ERROR on error
4369 """
4370 try:
4371 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004372 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004373 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4374 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004375 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004376 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004377 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004378 return main.FALSE
4379 else:
4380 main.log.error( self.name + ": setTestAdd did not" +
4381 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004382 main.log.debug( self.name + " actual: " + repr( output ) )
4383 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004384 except TypeError:
4385 main.log.exception( self.name + ": Object not as expected" )
4386 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004387 except Exception:
4388 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004389 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004390
4391 def setTestRemove( self, setName, values, clear=False, retain=False ):
4392 """
4393 CLI command to remove elements from a distributed set.
4394 Required arguments:
4395 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004396 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004397 Optional arguments:
4398 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004399 retain - Retain only the given values. (intersection of the
4400 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004401 returns:
4402 main.TRUE on success OR
4403 main.FALSE if the set was not changed OR
4404 main.ERROR on error
4405 """
4406 try:
4407 cmdStr = "set-test-remove "
4408 if clear:
4409 cmdStr += "-c " + str( setName )
4410 elif retain:
4411 cmdStr += "-r " + str( setName ) + " " + str( values )
4412 else:
4413 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004414 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004415 if clear:
4416 pattern = "Set " + str( setName ) + " cleared"
4417 if re.search( pattern, output ):
4418 return main.TRUE
4419 elif retain:
4420 positivePattern = str( setName ) + " was pruned to contain " +\
4421 "only elements of set \[(.*)\]"
4422 negativePattern = str( setName ) + " was not changed by " +\
4423 "retaining only elements of the set " +\
4424 "\[(.*)\]"
4425 if re.search( positivePattern, output ):
4426 return main.TRUE
4427 elif re.search( negativePattern, output ):
4428 return main.FALSE
4429 else:
4430 positivePattern = "\[(.*)\] was removed from the set " +\
4431 str( setName )
4432 if ( len( values.split() ) == 1 ):
4433 negativePattern = "\[(.*)\] was not in set " +\
4434 str( setName )
4435 else:
4436 negativePattern = "No element of \[(.*)\] was in set " +\
4437 str( setName )
4438 if re.search( positivePattern, output ):
4439 return main.TRUE
4440 elif re.search( negativePattern, output ):
4441 return main.FALSE
4442 main.log.error( self.name + ": setTestRemove did not" +
4443 " match expected output" )
4444 main.log.debug( self.name + " expected: " + pattern )
4445 main.log.debug( self.name + " actual: " + repr( output ) )
4446 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004447 except TypeError:
4448 main.log.exception( self.name + ": Object not as expected" )
4449 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004450 except Exception:
4451 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004452 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004453
4454 def setTestGet( self, setName, values="" ):
4455 """
4456 CLI command to get the elements in a distributed set.
4457 Required arguments:
4458 setName - The name of the set to remove from.
4459 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004460 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004461 returns:
4462 main.ERROR on error OR
4463 A list of elements in the set if no optional arguments are
4464 supplied OR
4465 A tuple containing the list then:
4466 main.FALSE if the given values are not in the set OR
4467 main.TRUE if the given values are in the set OR
4468 """
4469 try:
4470 values = str( values ).strip()
4471 setName = str( setName ).strip()
4472 length = len( values.split() )
4473 containsCheck = None
4474 # Patterns to match
4475 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004476 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004477 containsTrue = "Set " + setName + " contains the value " + values
4478 containsFalse = "Set " + setName + " did not contain the value " +\
4479 values
4480 containsAllTrue = "Set " + setName + " contains the the subset " +\
4481 setPattern
4482 containsAllFalse = "Set " + setName + " did not contain the the" +\
4483 " subset " + setPattern
4484
4485 cmdStr = "set-test-get "
4486 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004487 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004488 if length == 0:
4489 match = re.search( pattern, output )
4490 else: # if given values
4491 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004492 patternTrue = pattern + "\r\n" + containsTrue
4493 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004494 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004495 patternTrue = pattern + "\r\n" + containsAllTrue
4496 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004497 matchTrue = re.search( patternTrue, output )
4498 matchFalse = re.search( patternFalse, output )
4499 if matchTrue:
4500 containsCheck = main.TRUE
4501 match = matchTrue
4502 elif matchFalse:
4503 containsCheck = main.FALSE
4504 match = matchFalse
4505 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004506 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004507 "expected output" )
4508 main.log.debug( self.name + " expected: " + pattern )
4509 main.log.debug( self.name + " actual: " + repr( output ) )
4510 match = None
4511 if match:
4512 setMatch = match.group( 1 )
4513 if setMatch == '':
4514 setList = []
4515 else:
4516 setList = setMatch.split( ", " )
4517 if length > 0:
4518 return ( setList, containsCheck )
4519 else:
4520 return setList
4521 else: # no match
4522 main.log.error( self.name + ": setTestGet did not" +
4523 " match expected output" )
4524 main.log.debug( self.name + " expected: " + pattern )
4525 main.log.debug( self.name + " actual: " + repr( output ) )
4526 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004527 except TypeError:
4528 main.log.exception( self.name + ": Object not as expected" )
4529 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004530 except Exception:
4531 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004532 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004533
4534 def setTestSize( self, setName ):
4535 """
4536 CLI command to get the elements in a distributed set.
4537 Required arguments:
4538 setName - The name of the set to remove from.
4539 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004540 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004541 None on error
4542 """
4543 try:
4544 # TODO: Should this check against the number of elements returned
4545 # and then return true/false based on that?
4546 setName = str( setName ).strip()
4547 # Patterns to match
4548 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004549 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004550 setPattern
4551 cmdStr = "set-test-get -s "
4552 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004553 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004554 if output:
4555 match = re.search( pattern, output )
4556 if match:
4557 setSize = int( match.group( 1 ) )
4558 setMatch = match.group( 2 )
4559 if len( setMatch.split() ) == setSize:
4560 main.log.info( "The size returned by " + self.name +
4561 " matches the number of elements in " +
4562 "the returned set" )
4563 else:
4564 main.log.error( "The size returned by " + self.name +
4565 " does not match the number of " +
4566 "elements in the returned set." )
4567 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004568 else: # no match
4569 main.log.error( self.name + ": setTestGet did not" +
4570 " match expected output" )
4571 main.log.debug( self.name + " expected: " + pattern )
4572 main.log.debug( self.name + " actual: " + repr( output ) )
4573 return None
Jon Hall390696c2015-05-05 17:13:41 -07004574 except TypeError:
4575 main.log.exception( self.name + ": Object not as expected" )
4576 return None
Jon Hall390696c2015-05-05 17:13:41 -07004577 except Exception:
4578 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004579 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004580
Jon Hall80daded2015-05-27 16:07:00 -07004581 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004582 """
4583 Command to list the various counters in the system.
4584 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004585 if jsonFormat, a string of the json object returned by the cli
4586 command
4587 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004588 None on error
4589 """
Jon Hall390696c2015-05-05 17:13:41 -07004590 try:
Jon Hall390696c2015-05-05 17:13:41 -07004591 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004592 if jsonFormat:
4593 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004594 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004595 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004596 assert "Command not found:" not in output, output
4597 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004598 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004599 return output
Jon Hall390696c2015-05-05 17:13:41 -07004600 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004601 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004602 return None
Jon Hall390696c2015-05-05 17:13:41 -07004603 except TypeError:
4604 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004605 return None
Jon Hall390696c2015-05-05 17:13:41 -07004606 except pexpect.EOF:
4607 main.log.error( self.name + ": EOF exception found" )
4608 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004609 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004610 except Exception:
4611 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004612 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004613
Jon Hall935db192016-04-19 00:22:04 -07004614 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004615 """
Jon Halle1a3b752015-07-22 13:02:46 -07004616 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004617 Required arguments:
4618 counter - The name of the counter to increment.
4619 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004620 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004621 returns:
4622 integer value of the counter or
4623 None on Error
4624 """
4625 try:
4626 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004627 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004628 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004629 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004630 if delta != 1:
4631 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004632 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004633 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004634 match = re.search( pattern, output )
4635 if match:
4636 return int( match.group( 1 ) )
4637 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004638 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004639 " match expected output." )
4640 main.log.debug( self.name + " expected: " + pattern )
4641 main.log.debug( self.name + " actual: " + repr( output ) )
4642 return None
Jon Hall390696c2015-05-05 17:13:41 -07004643 except TypeError:
4644 main.log.exception( self.name + ": Object not as expected" )
4645 return None
Jon Hall390696c2015-05-05 17:13:41 -07004646 except Exception:
4647 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004648 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004649
Jon Hall935db192016-04-19 00:22:04 -07004650 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004651 """
4652 CLI command to get a distributed counter then add a delta to it.
4653 Required arguments:
4654 counter - The name of the counter to increment.
4655 Optional arguments:
4656 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004657 returns:
4658 integer value of the counter or
4659 None on Error
4660 """
4661 try:
4662 counter = str( counter )
4663 delta = int( delta )
4664 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004665 cmdStr += counter
4666 if delta != 1:
4667 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004668 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004669 pattern = counter + " was updated to (-?\d+)"
4670 match = re.search( pattern, output )
4671 if match:
4672 return int( match.group( 1 ) )
4673 else:
4674 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4675 " match expected output." )
4676 main.log.debug( self.name + " expected: " + pattern )
4677 main.log.debug( self.name + " actual: " + repr( output ) )
4678 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004679 except TypeError:
4680 main.log.exception( self.name + ": Object not as expected" )
4681 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004682 except Exception:
4683 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004684 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004685
4686 def valueTestGet( self, valueName ):
4687 """
4688 CLI command to get the value of an atomic value.
4689 Required arguments:
4690 valueName - The name of the value to get.
4691 returns:
4692 string value of the value or
4693 None on Error
4694 """
4695 try:
4696 valueName = str( valueName )
4697 cmdStr = "value-test "
4698 operation = "get"
4699 cmdStr = "value-test {} {}".format( valueName,
4700 operation )
4701 output = self.distPrimitivesSend( cmdStr )
4702 pattern = "(\w+)"
4703 match = re.search( pattern, output )
4704 if match:
4705 return match.group( 1 )
4706 else:
4707 main.log.error( self.name + ": valueTestGet did not" +
4708 " match expected output." )
4709 main.log.debug( self.name + " expected: " + pattern )
4710 main.log.debug( self.name + " actual: " + repr( output ) )
4711 return None
4712 except TypeError:
4713 main.log.exception( self.name + ": Object not as expected" )
4714 return None
4715 except Exception:
4716 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004717 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004718
4719 def valueTestSet( self, valueName, newValue ):
4720 """
4721 CLI command to set the value of an atomic value.
4722 Required arguments:
4723 valueName - The name of the value to set.
4724 newValue - The value to assign to the given value.
4725 returns:
4726 main.TRUE on success or
4727 main.ERROR on Error
4728 """
4729 try:
4730 valueName = str( valueName )
4731 newValue = str( newValue )
4732 operation = "set"
4733 cmdStr = "value-test {} {} {}".format( valueName,
4734 operation,
4735 newValue )
4736 output = self.distPrimitivesSend( cmdStr )
4737 if output is not None:
4738 return main.TRUE
4739 else:
4740 return main.ERROR
4741 except TypeError:
4742 main.log.exception( self.name + ": Object not as expected" )
4743 return main.ERROR
4744 except Exception:
4745 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004746 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004747
4748 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4749 """
4750 CLI command to compareAndSet the value of an atomic value.
4751 Required arguments:
4752 valueName - The name of the value.
4753 oldValue - Compare the current value of the atomic value to this
4754 newValue - If the value equals oldValue, set the value to newValue
4755 returns:
4756 main.TRUE on success or
4757 main.FALSE on failure or
4758 main.ERROR on Error
4759 """
4760 try:
4761 valueName = str( valueName )
4762 oldValue = str( oldValue )
4763 newValue = str( newValue )
4764 operation = "compareAndSet"
4765 cmdStr = "value-test {} {} {} {}".format( valueName,
4766 operation,
4767 oldValue,
4768 newValue )
4769 output = self.distPrimitivesSend( cmdStr )
4770 pattern = "(\w+)"
4771 match = re.search( pattern, output )
4772 if match:
4773 result = match.group( 1 )
4774 if result == "true":
4775 return main.TRUE
4776 elif result == "false":
4777 return main.FALSE
4778 else:
4779 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4780 " match expected output." )
4781 main.log.debug( self.name + " expected: " + pattern )
4782 main.log.debug( self.name + " actual: " + repr( output ) )
4783 return main.ERROR
4784 except TypeError:
4785 main.log.exception( self.name + ": Object not as expected" )
4786 return main.ERROR
4787 except Exception:
4788 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004789 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004790
4791 def valueTestGetAndSet( self, valueName, newValue ):
4792 """
4793 CLI command to getAndSet the value of an atomic value.
4794 Required arguments:
4795 valueName - The name of the value to get.
4796 newValue - The value to assign to the given value
4797 returns:
4798 string value of the value or
4799 None on Error
4800 """
4801 try:
4802 valueName = str( valueName )
4803 cmdStr = "value-test "
4804 operation = "getAndSet"
4805 cmdStr += valueName + " " + operation
4806 cmdStr = "value-test {} {} {}".format( valueName,
4807 operation,
4808 newValue )
4809 output = self.distPrimitivesSend( cmdStr )
4810 pattern = "(\w+)"
4811 match = re.search( pattern, output )
4812 if match:
4813 return match.group( 1 )
4814 else:
4815 main.log.error( self.name + ": valueTestGetAndSet did not" +
4816 " match expected output." )
4817 main.log.debug( self.name + " expected: " + pattern )
4818 main.log.debug( self.name + " actual: " + repr( output ) )
4819 return None
4820 except TypeError:
4821 main.log.exception( self.name + ": Object not as expected" )
4822 return None
4823 except Exception:
4824 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004825 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004826
4827 def valueTestDestroy( self, valueName ):
4828 """
4829 CLI command to destroy an atomic value.
4830 Required arguments:
4831 valueName - The name of the value to destroy.
4832 returns:
4833 main.TRUE on success or
4834 main.ERROR on Error
4835 """
4836 try:
4837 valueName = str( valueName )
4838 cmdStr = "value-test "
4839 operation = "destroy"
4840 cmdStr += valueName + " " + operation
4841 output = self.distPrimitivesSend( cmdStr )
4842 if output is not None:
4843 return main.TRUE
4844 else:
4845 return main.ERROR
4846 except TypeError:
4847 main.log.exception( self.name + ": Object not as expected" )
4848 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004849 except Exception:
4850 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004851 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004852
YPZhangfebf7302016-05-24 16:45:56 -07004853 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004854 """
4855 Description: Execute summary command in onos
4856 Returns: json object ( summary -j ), returns main.FALSE if there is
4857 no output
4858
4859 """
4860 try:
4861 cmdStr = "summary"
4862 if jsonFormat:
4863 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004864 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004865 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004866 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004867 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004868 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004869 if not handle:
4870 main.log.error( self.name + ": There is no output in " +
4871 "summary command" )
4872 return main.FALSE
4873 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004874 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004875 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004876 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004877 except TypeError:
4878 main.log.exception( self.name + ": Object not as expected" )
4879 return None
4880 except pexpect.EOF:
4881 main.log.error( self.name + ": EOF exception found" )
4882 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004883 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004884 except Exception:
4885 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004886 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004887
Jon Hall935db192016-04-19 00:22:04 -07004888 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004889 """
4890 CLI command to get the value of a key in a consistent map using
4891 transactions. This a test function and can only get keys from the
4892 test map hard coded into the cli command
4893 Required arguments:
4894 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004895 returns:
4896 The string value of the key or
4897 None on Error
4898 """
4899 try:
4900 keyName = str( keyName )
4901 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004902 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004903 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004904 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4905 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004906 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004907 return None
4908 else:
4909 match = re.search( pattern, output )
4910 if match:
4911 return match.groupdict()[ 'value' ]
4912 else:
4913 main.log.error( self.name + ": transactionlMapGet did not" +
4914 " match expected output." )
4915 main.log.debug( self.name + " expected: " + pattern )
4916 main.log.debug( self.name + " actual: " + repr( output ) )
4917 return None
4918 except TypeError:
4919 main.log.exception( self.name + ": Object not as expected" )
4920 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004921 except Exception:
4922 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004923 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004924
Jon Hall935db192016-04-19 00:22:04 -07004925 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004926 """
4927 CLI command to put a value into 'numKeys' number of keys in a
4928 consistent map using transactions. This a test function and can only
4929 put into keys named 'Key#' of the test map hard coded into the cli command
4930 Required arguments:
4931 numKeys - Number of keys to add the value to
4932 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004933 returns:
4934 A dictionary whose keys are the name of the keys put into the map
4935 and the values of the keys are dictionaries whose key-values are
4936 'value': value put into map and optionaly
4937 'oldValue': Previous value in the key or
4938 None on Error
4939
4940 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004941 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4942 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004943 """
4944 try:
4945 numKeys = str( numKeys )
4946 value = str( value )
4947 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004948 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004949 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004950 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4951 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4952 results = {}
4953 for line in output.splitlines():
4954 new = re.search( newPattern, line )
4955 updated = re.search( updatedPattern, line )
4956 if new:
4957 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4958 elif updated:
4959 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004960 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004961 else:
4962 main.log.error( self.name + ": transactionlMapGet did not" +
4963 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004964 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4965 newPattern,
4966 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004967 main.log.debug( self.name + " actual: " + repr( output ) )
4968 return results
Jon Hall0e240372018-05-02 11:21:57 -07004969 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004970 main.log.exception( self.name + ": Object not as expected" )
4971 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004972 except Exception:
4973 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004974 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004975
acsmarsdaea66c2015-09-03 11:44:06 -07004976 def maps( self, jsonFormat=True ):
4977 """
4978 Description: Returns result of onos:maps
4979 Optional:
4980 * jsonFormat: enable json formatting of output
4981 """
4982 try:
4983 cmdStr = "maps"
4984 if jsonFormat:
4985 cmdStr += " -j"
4986 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004987 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004988 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004989 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004990 except AssertionError:
4991 main.log.exception( "" )
4992 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004993 except TypeError:
4994 main.log.exception( self.name + ": Object not as expected" )
4995 return None
4996 except pexpect.EOF:
4997 main.log.error( self.name + ": EOF exception found" )
4998 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004999 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07005000 except Exception:
5001 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005002 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005003
5004 def getSwController( self, uri, jsonFormat=True ):
5005 """
5006 Descrition: Gets the controller information from the device
5007 """
5008 try:
5009 cmd = "device-controllers "
5010 if jsonFormat:
5011 cmd += "-j "
5012 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07005013 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005014 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005015 return response
Jon Hallc6793552016-01-19 14:18:37 -08005016 except AssertionError:
5017 main.log.exception( "" )
5018 return None
GlennRC050596c2015-11-18 17:06:41 -08005019 except TypeError:
5020 main.log.exception( self.name + ": Object not as expected" )
5021 return None
5022 except pexpect.EOF:
5023 main.log.error( self.name + ": EOF exception found" )
5024 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005025 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005026 except Exception:
5027 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005028 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005029
5030 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
5031 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005032 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08005033
5034 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005035 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08005036 ip - String or List: The ip address of the controller.
5037 This parameter can be formed in a couple of different ways.
5038 VALID:
5039 10.0.0.1 - just the ip address
5040 tcp:10.0.0.1 - the protocol and the ip address
5041 tcp:10.0.0.1:6653 - the protocol and port can be specified,
5042 so that you can add controllers with different
5043 protocols and ports
5044 INVALID:
5045 10.0.0.1:6653 - this is not supported by ONOS
5046
5047 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
5048 port - The port number.
5049 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
5050
5051 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
5052 """
5053 try:
5054 cmd = "device-setcontrollers"
5055
5056 if jsonFormat:
5057 cmd += " -j"
5058 cmd += " " + uri
5059 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005060 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08005061 for item in ip:
5062 if ":" in item:
5063 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005064 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08005065 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005066 elif "." in sitem[ 1 ]:
5067 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08005068 else:
5069 main.log.error( "Malformed entry: " + item )
5070 raise TypeError
5071 else:
5072 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08005073 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07005074 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005075 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005076 if "Error" in response:
5077 main.log.error( response )
5078 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005079 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005080 except AssertionError:
5081 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005082 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005083 except TypeError:
5084 main.log.exception( self.name + ": Object not as expected" )
5085 return main.FALSE
5086 except pexpect.EOF:
5087 main.log.error( self.name + ": EOF exception found" )
5088 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005089 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005090 except Exception:
5091 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005092 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005093
5094 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005095 '''
GlennRC20fc6522015-12-23 23:26:57 -08005096 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005097 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005098 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005099 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005100 Returns:
5101 Returns main.FALSE if an exception is thrown or an error is present
5102 in the response. Otherwise, returns main.TRUE.
5103 NOTE:
5104 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005105 '''
GlennRC20fc6522015-12-23 23:26:57 -08005106 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005107 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005108 deviceStr = device
5109 device = []
5110 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005111
5112 for d in device:
5113 time.sleep( 1 )
5114 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005115 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005116 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005117 if "Error" in response:
5118 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5119 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005120 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005121 except AssertionError:
5122 main.log.exception( "" )
5123 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005124 except TypeError:
5125 main.log.exception( self.name + ": Object not as expected" )
5126 return main.FALSE
5127 except pexpect.EOF:
5128 main.log.error( self.name + ": EOF exception found" )
5129 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005130 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005131 except Exception:
5132 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005133 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005134
5135 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005136 '''
GlennRC20fc6522015-12-23 23:26:57 -08005137 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005138 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005139 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005140 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005141 Returns:
5142 Returns main.FALSE if an exception is thrown or an error is present
5143 in the response. Otherwise, returns main.TRUE.
5144 NOTE:
5145 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005146 '''
GlennRC20fc6522015-12-23 23:26:57 -08005147 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005148 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005149 host = list( host )
5150
5151 for h in host:
5152 time.sleep( 1 )
5153 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005154 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005155 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005156 if "Error" in response:
5157 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5158 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005159 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005160 except AssertionError:
5161 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005162 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005163 except TypeError:
5164 main.log.exception( self.name + ": Object not as expected" )
5165 return main.FALSE
5166 except pexpect.EOF:
5167 main.log.error( self.name + ": EOF exception found" )
5168 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005169 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005170 except Exception:
5171 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005172 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005173
YPZhangfebf7302016-05-24 16:45:56 -07005174 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005175 '''
GlennRCed771242016-01-13 17:02:47 -08005176 Description:
5177 Bring link down or up in the null-provider.
5178 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005179 begin - (string) One end of a device or switch.
5180 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005181 returns:
5182 main.TRUE if no exceptions were thrown and no Errors are
5183 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005184 '''
GlennRCed771242016-01-13 17:02:47 -08005185 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005186 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005187 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005188 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005189 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005190 if "Error" in response or "Failure" in response:
5191 main.log.error( response )
5192 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005193 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005194 except AssertionError:
5195 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005196 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005197 except TypeError:
5198 main.log.exception( self.name + ": Object not as expected" )
5199 return main.FALSE
5200 except pexpect.EOF:
5201 main.log.error( self.name + ": EOF exception found" )
5202 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005203 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005204 except Exception:
5205 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005206 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005207
Jon Hall2c8959e2016-12-16 12:17:34 -08005208 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005209 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005210 Description:
5211 Changes the state of port in an OF switch by means of the
5212 PORTSTATUS OF messages.
5213 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005214 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5215 port - (string) target port in the device. Ex: '2'
5216 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005217 returns:
5218 main.TRUE if no exceptions were thrown and no Errors are
5219 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005220 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005221 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005222 state = state.lower()
5223 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005224 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005225 response = self.sendline( cmd, showResponse=True )
5226 assert response is not None, "Error in sendline"
5227 assert "Command not found:" not in response, response
5228 if "Error" in response or "Failure" in response:
5229 main.log.error( response )
5230 return main.FALSE
5231 return main.TRUE
5232 except AssertionError:
5233 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005234 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005235 except TypeError:
5236 main.log.exception( self.name + ": Object not as expected" )
5237 return main.FALSE
5238 except pexpect.EOF:
5239 main.log.error( self.name + ": EOF exception found" )
5240 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005241 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005242 except Exception:
5243 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005244 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005245
5246 def logSet( self, level="INFO", app="org.onosproject" ):
5247 """
5248 Set the logging level to lvl for a specific app
5249 returns main.TRUE on success
5250 returns main.FALSE if Error occurred
5251 if noExit is True, TestON will not exit, but clean up
5252 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5253 Level defaults to INFO
5254 """
5255 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005256 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -08005257 self.handle.expect( self.karafPrompt )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005258
5259 response = self.handle.before
5260 if re.search( "Error", response ):
5261 return main.FALSE
5262 return main.TRUE
5263 except pexpect.TIMEOUT:
5264 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005265 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005266 except pexpect.EOF:
5267 main.log.error( self.name + ": EOF exception found" )
5268 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005269 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005270 except Exception:
5271 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005272 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005273
5274 def getGraphDict( self, timeout=60, includeHost=False ):
5275 """
5276 Return a dictionary which describes the latest network topology data as a
5277 graph.
5278 An example of the dictionary:
5279 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5280 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5281 Each vertex should at least have an 'edges' attribute which describes the
5282 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005283 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005284 list of attributes.
5285 An example of the edges dictionary:
5286 'edges': { vertex2: { 'port': ..., 'weight': ... },
5287 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005288 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005289 in topology data.
5290 """
5291 graphDict = {}
5292 try:
5293 links = self.links()
5294 links = json.loads( links )
5295 devices = self.devices()
5296 devices = json.loads( devices )
5297 idToDevice = {}
5298 for device in devices:
5299 idToDevice[ device[ 'id' ] ] = device
5300 if includeHost:
5301 hosts = self.hosts()
5302 # FIXME: support 'includeHost' argument
5303 for link in links:
5304 nodeA = link[ 'src' ][ 'device' ]
5305 nodeB = link[ 'dst' ][ 'device' ]
5306 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005307 if nodeA not in graphDict.keys():
5308 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005309 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005310 'type': idToDevice[ nodeA ][ 'type' ],
5311 'available': idToDevice[ nodeA ][ 'available' ],
5312 'role': idToDevice[ nodeA ][ 'role' ],
5313 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5314 'hw': idToDevice[ nodeA ][ 'hw' ],
5315 'sw': idToDevice[ nodeA ][ 'sw' ],
5316 'serial': idToDevice[ nodeA ][ 'serial' ],
5317 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005318 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005319 else:
5320 # Assert nodeB is not connected to any current links of nodeA
5321 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005322 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5323 'type': link[ 'type' ],
5324 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005325 return graphDict
5326 except ( TypeError, ValueError ):
5327 main.log.exception( self.name + ": Object not as expected" )
5328 return None
5329 except KeyError:
5330 main.log.exception( self.name + ": KeyError exception found" )
5331 return None
5332 except AssertionError:
5333 main.log.exception( self.name + ": AssertionError exception found" )
5334 return None
5335 except pexpect.EOF:
5336 main.log.error( self.name + ": EOF exception found" )
5337 main.log.error( self.name + ": " + self.handle.before )
5338 return None
5339 except Exception:
5340 main.log.exception( self.name + ": Uncaught exception!" )
5341 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005342
5343 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005344 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005345 Send command to check intent-perf summary
5346 Returns: dictionary for intent-perf summary
5347 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005348 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005349 cmd = "intent-perf -s"
5350 respDic = {}
5351 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005352 assert resp is not None, "Error in sendline"
5353 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005354 try:
5355 # Generate the dictionary to return
5356 for l in resp.split( "\n" ):
5357 # Delete any white space in line
5358 temp = re.sub( r'\s+', '', l )
5359 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005360 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005361
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005362 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005363 main.log.exception( self.name + ": Object not as expected" )
5364 return None
5365 except KeyError:
5366 main.log.exception( self.name + ": KeyError exception found" )
5367 return None
5368 except AssertionError:
5369 main.log.exception( self.name + ": AssertionError exception found" )
5370 return None
5371 except pexpect.EOF:
5372 main.log.error( self.name + ": EOF exception found" )
5373 main.log.error( self.name + ": " + self.handle.before )
5374 return None
5375 except Exception:
5376 main.log.exception( self.name + ": Uncaught exception!" )
5377 return None
5378 return respDic
5379
Chiyu Chengec63bde2016-11-17 18:11:36 -08005380 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005381 """
5382 Searches the latest ONOS log file for the given search term and
5383 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005384
chengchiyu08303a02016-09-08 17:40:26 -07005385 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005386 searchTerm:
5387 The string to grep from the ONOS log.
5388 startLine:
5389 The term that decides which line is the start to search the searchTerm in
5390 the karaf log. For now, startTerm only works in 'first' mode.
5391 logNum:
5392 In some extreme cases, one karaf log is not big enough to contain all the
5393 information.Because of this, search mutiply logs is necessary to capture
5394 the right result. logNum is the number of karaf logs that we need to search
5395 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005396 mode:
5397 all: return all the strings that contain the search term
5398 last: return the last string that contains the search term
5399 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005400 num: return the number of times that the searchTerm appears in the log
5401 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005402 """
5403 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005404 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005405 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005406 logPath = '/opt/onos/log/karaf.log.'
5407 logPaths = '/opt/onos/log/karaf.log'
5408 for i in range( 1, logNum ):
5409 logPaths = logPath + str( i ) + " " + logPaths
5410 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005411 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005412 # 100000000 is just a extreme large number to make sure this function can
5413 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005414 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005415 if mode == 'all':
5416 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005417 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005418 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005419 elif mode == 'first':
5420 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5421 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005422 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005423 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005424 return num
You Wang6d301d42017-04-21 10:49:33 -07005425 elif mode == 'total':
Jon Halld5a94fb2018-11-13 14:32:23 -08005426 totalLines = self.lineCount( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005427 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005428 else:
5429 main.log.error( self.name + " unsupported mode" )
5430 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005431 before = self.sendline( cmd )
5432 before = before.splitlines()
5433 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005434 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005435 return returnLines
5436 except AssertionError:
5437 main.log.error( self.name + " searchTerm is not string type" )
5438 return None
5439 except pexpect.EOF:
5440 main.log.error( self.name + ": EOF exception found" )
5441 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005442 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005443 except pexpect.TIMEOUT:
5444 main.log.error( self.name + ": TIMEOUT exception found" )
5445 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005446 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005447 except Exception:
5448 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005449 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005450
5451 def vplsShow( self, jsonFormat=True ):
5452 """
5453 Description: Returns result of onos:vpls show, which should list the
5454 configured VPLS networks and the assigned interfaces.
5455 Optional:
5456 * jsonFormat: enable json formatting of output
5457 Returns:
5458 The output of the command or None on error.
5459 """
5460 try:
5461 cmdStr = "vpls show"
5462 if jsonFormat:
5463 raise NotImplementedError
5464 cmdStr += " -j"
5465 handle = self.sendline( cmdStr )
5466 assert handle is not None, "Error in sendline"
5467 assert "Command not found:" not in handle, handle
5468 return handle
5469 except AssertionError:
5470 main.log.exception( "" )
5471 return None
5472 except TypeError:
5473 main.log.exception( self.name + ": Object not as expected" )
5474 return None
5475 except pexpect.EOF:
5476 main.log.error( self.name + ": EOF exception found" )
5477 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005478 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005479 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005480 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005481 return None
5482 except Exception:
5483 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005484 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005485
5486 def parseVplsShow( self ):
5487 """
5488 Parse the cli output of 'vpls show' into json output. This is required
5489 as there is currently no json output available.
5490 """
5491 try:
5492 output = []
5493 raw = self.vplsShow( jsonFormat=False )
5494 namePat = "VPLS name: (?P<name>\w+)"
5495 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5496 encapPat = "Encapsulation: (?P<encap>\w+)"
5497 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5498 mIter = re.finditer( pattern, raw )
5499 for match in mIter:
5500 item = {}
5501 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005502 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005503 if ifaces == [ "" ]:
5504 ifaces = []
5505 item[ 'interfaces' ] = ifaces
5506 encap = match.group( 'encap' )
5507 if encap != 'NONE':
5508 item[ 'encapsulation' ] = encap.lower()
5509 output.append( item )
5510 return output
5511 except Exception:
5512 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005513 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005514
5515 def vplsList( self, jsonFormat=True ):
5516 """
5517 Description: Returns result of onos:vpls list, which should list the
5518 configured VPLS networks.
5519 Optional:
5520 * jsonFormat: enable json formatting of output
5521 """
5522 try:
5523 cmdStr = "vpls list"
5524 if jsonFormat:
5525 raise NotImplementedError
5526 cmdStr += " -j"
5527 handle = self.sendline( cmdStr )
5528 assert handle is not None, "Error in sendline"
5529 assert "Command not found:" not in handle, handle
5530 return handle
5531 except AssertionError:
5532 main.log.exception( "" )
5533 return None
5534 except TypeError:
5535 main.log.exception( self.name + ": Object not as expected" )
5536 return None
5537 except pexpect.EOF:
5538 main.log.error( self.name + ": EOF exception found" )
5539 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005540 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005541 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005542 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005543 return None
5544 except Exception:
5545 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005546 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005547
5548 def vplsCreate( self, network ):
5549 """
5550 CLI command to create a new VPLS network.
5551 Required arguments:
5552 network - String name of the network to create.
5553 returns:
5554 main.TRUE on success and main.FALSE on failure
5555 """
5556 try:
5557 network = str( network )
5558 cmdStr = "vpls create "
5559 cmdStr += network
5560 output = self.sendline( cmdStr )
5561 assert output is not None, "Error in sendline"
5562 assert "Command not found:" not in output, output
5563 assert "Error executing command" not in output, output
5564 assert "VPLS already exists:" not in output, output
5565 return main.TRUE
5566 except AssertionError:
5567 main.log.exception( "" )
5568 return main.FALSE
5569 except TypeError:
5570 main.log.exception( self.name + ": Object not as expected" )
5571 return main.FALSE
5572 except pexpect.EOF:
5573 main.log.error( self.name + ": EOF exception found" )
5574 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005575 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005576 except Exception:
5577 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005578 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005579
5580 def vplsDelete( self, network ):
5581 """
5582 CLI command to delete a VPLS network.
5583 Required arguments:
5584 network - Name of the network to delete.
5585 returns:
5586 main.TRUE on success and main.FALSE on failure
5587 """
5588 try:
5589 network = str( network )
5590 cmdStr = "vpls delete "
5591 cmdStr += network
5592 output = self.sendline( cmdStr )
5593 assert output is not None, "Error in sendline"
5594 assert "Command not found:" not in output, output
5595 assert "Error executing command" not in output, output
5596 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005597 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005598 return main.TRUE
5599 except AssertionError:
5600 main.log.exception( "" )
5601 return main.FALSE
5602 except TypeError:
5603 main.log.exception( self.name + ": Object not as expected" )
5604 return main.FALSE
5605 except pexpect.EOF:
5606 main.log.error( self.name + ": EOF exception found" )
5607 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005608 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005609 except Exception:
5610 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005611 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005612
5613 def vplsAddIface( self, network, iface ):
5614 """
5615 CLI command to add an interface to a VPLS network.
5616 Required arguments:
5617 network - Name of the network to add the interface to.
5618 iface - The ONOS name for an interface.
5619 returns:
5620 main.TRUE on success and main.FALSE on failure
5621 """
5622 try:
5623 network = str( network )
5624 iface = str( iface )
5625 cmdStr = "vpls add-if "
5626 cmdStr += network + " " + iface
5627 output = self.sendline( cmdStr )
5628 assert output is not None, "Error in sendline"
5629 assert "Command not found:" not in output, output
5630 assert "Error executing command" not in output, output
5631 assert "already associated to network" not in output, output
5632 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005633 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005634 return main.TRUE
5635 except AssertionError:
5636 main.log.exception( "" )
5637 return main.FALSE
5638 except TypeError:
5639 main.log.exception( self.name + ": Object not as expected" )
5640 return main.FALSE
5641 except pexpect.EOF:
5642 main.log.error( self.name + ": EOF exception found" )
5643 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005644 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005645 except Exception:
5646 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005647 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005648
5649 def vplsRemIface( self, network, iface ):
5650 """
5651 CLI command to remove an interface from a VPLS network.
5652 Required arguments:
5653 network - Name of the network to remove the interface from.
5654 iface - Name of the interface to remove.
5655 returns:
5656 main.TRUE on success and main.FALSE on failure
5657 """
5658 try:
5659 iface = str( iface )
5660 cmdStr = "vpls rem-if "
5661 cmdStr += network + " " + iface
5662 output = self.sendline( cmdStr )
5663 assert output is not None, "Error in sendline"
5664 assert "Command not found:" not in output, output
5665 assert "Error executing command" not in output, output
5666 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005667 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005668 return main.TRUE
5669 except AssertionError:
5670 main.log.exception( "" )
5671 return main.FALSE
5672 except TypeError:
5673 main.log.exception( self.name + ": Object not as expected" )
5674 return main.FALSE
5675 except pexpect.EOF:
5676 main.log.error( self.name + ": EOF exception found" )
5677 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005678 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005679 except Exception:
5680 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005681 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005682
5683 def vplsClean( self ):
5684 """
5685 Description: Clears the VPLS app configuration.
5686 Returns: main.TRUE on success and main.FALSE on failure
5687 """
5688 try:
5689 cmdStr = "vpls clean"
5690 handle = self.sendline( cmdStr )
5691 assert handle is not None, "Error in sendline"
5692 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005693 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005694 return handle
5695 except AssertionError:
5696 main.log.exception( "" )
5697 return main.FALSE
5698 except TypeError:
5699 main.log.exception( self.name + ": Object not as expected" )
5700 return main.FALSE
5701 except pexpect.EOF:
5702 main.log.error( self.name + ": EOF exception found" )
5703 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005704 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005705 except Exception:
5706 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005707 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005708
5709 def vplsSetEncap( self, network, encapType ):
5710 """
5711 CLI command to add an interface to a VPLS network.
5712 Required arguments:
5713 network - Name of the network to create.
5714 encapType - Type of encapsulation.
5715 returns:
5716 main.TRUE on success and main.FALSE on failure
5717 """
5718 try:
5719 network = str( network )
5720 encapType = str( encapType ).upper()
5721 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5722 cmdStr = "vpls set-encap "
5723 cmdStr += network + " " + encapType
5724 output = self.sendline( cmdStr )
5725 assert output is not None, "Error in sendline"
5726 assert "Command not found:" not in output, output
5727 assert "Error executing command" not in output, output
5728 assert "already associated to network" not in output, output
5729 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005730 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005731 return main.TRUE
5732 except AssertionError:
5733 main.log.exception( "" )
5734 return main.FALSE
5735 except TypeError:
5736 main.log.exception( self.name + ": Object not as expected" )
5737 return main.FALSE
5738 except pexpect.EOF:
5739 main.log.error( self.name + ": EOF exception found" )
5740 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005741 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005742 except Exception:
5743 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005744 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005745
5746 def interfaces( self, jsonFormat=True ):
5747 """
5748 Description: Returns result of interfaces command.
5749 Optional:
5750 * jsonFormat: enable json formatting of output
5751 Returns:
5752 The output of the command or None on error.
5753 """
5754 try:
5755 cmdStr = "interfaces"
5756 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005757 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005758 cmdStr += " -j"
5759 handle = self.sendline( cmdStr )
5760 assert handle is not None, "Error in sendline"
5761 assert "Command not found:" not in handle, handle
5762 return handle
5763 except AssertionError:
5764 main.log.exception( "" )
5765 return None
5766 except TypeError:
5767 main.log.exception( self.name + ": Object not as expected" )
5768 return None
5769 except pexpect.EOF:
5770 main.log.error( self.name + ": EOF exception found" )
5771 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005772 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005773 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005774 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005775 return None
5776 except Exception:
5777 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005778 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005779
5780 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005781 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005782 Get the timestamp of searchTerm from karaf log.
5783
5784 Arguments:
5785 splitTerm_before and splitTerm_after:
5786
5787 The terms that split the string that contains the timeStamp of
5788 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5789 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5790 and the splitTerm_after is "x"
5791
5792 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005793 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005794 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005795 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005796 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005797 return main.ERROR
5798 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005799 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005800 main.log.warn( "Captured timestamp string is empty" )
5801 return main.ERROR
5802 lines = lines[ 0 ]
5803 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005804 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005805 # get the target value
5806 line = lines.split( splitTerm_before )
5807 key = line[ 1 ].split( splitTerm_after )
5808 return int( key[ 0 ] )
5809 except IndexError:
5810 main.log.warn( "Index Error!" )
5811 return main.ERROR
5812 except AssertionError:
5813 main.log.warn( "Search Term Not Found " )
5814 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005815
5816 def workQueueAdd( self, queueName, value ):
5817 """
5818 CLI command to add a string to the specified Work Queue.
5819 This function uses the distributed primitives test app, which
5820 gives some cli access to distributed primitives for testing
5821 purposes only.
5822
5823 Required arguments:
5824 queueName - The name of the queue to add to
5825 value - The value to add to the queue
5826 returns:
5827 main.TRUE on success, main.FALSE on failure and
5828 main.ERROR on error.
5829 """
5830 try:
5831 queueName = str( queueName )
5832 value = str( value )
5833 prefix = "work-queue-test"
5834 operation = "add"
5835 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5836 output = self.distPrimitivesSend( cmdStr )
5837 if "Invalid operation name" in output:
5838 main.log.warn( output )
5839 return main.ERROR
5840 elif "Done" in output:
5841 return main.TRUE
5842 except TypeError:
5843 main.log.exception( self.name + ": Object not as expected" )
5844 return main.ERROR
5845 except Exception:
5846 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005847 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005848
5849 def workQueueAddMultiple( self, queueName, value1, value2 ):
5850 """
5851 CLI command to add two strings to the specified Work Queue.
5852 This function uses the distributed primitives test app, which
5853 gives some cli access to distributed primitives for testing
5854 purposes only.
5855
5856 Required arguments:
5857 queueName - The name of the queue to add to
5858 value1 - The first value to add to the queue
5859 value2 - The second value to add to the queue
5860 returns:
5861 main.TRUE on success, main.FALSE on failure and
5862 main.ERROR on error.
5863 """
5864 try:
5865 queueName = str( queueName )
5866 value1 = str( value1 )
5867 value2 = str( value2 )
5868 prefix = "work-queue-test"
5869 operation = "addMultiple"
5870 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5871 output = self.distPrimitivesSend( cmdStr )
5872 if "Invalid operation name" in output:
5873 main.log.warn( output )
5874 return main.ERROR
5875 elif "Done" in output:
5876 return main.TRUE
5877 except TypeError:
5878 main.log.exception( self.name + ": Object not as expected" )
5879 return main.ERROR
5880 except Exception:
5881 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005882 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005883
5884 def workQueueTakeAndComplete( self, queueName, number=1 ):
5885 """
5886 CLI command to take a value from the specified Work Queue and compelte it.
5887 This function uses the distributed primitives test app, which
5888 gives some cli access to distributed primitives for testing
5889 purposes only.
5890
5891 Required arguments:
5892 queueName - The name of the queue to add to
5893 number - The number of items to take and complete
5894 returns:
5895 main.TRUE on success, main.FALSE on failure and
5896 main.ERROR on error.
5897 """
5898 try:
5899 queueName = str( queueName )
5900 number = str( int( number ) )
5901 prefix = "work-queue-test"
5902 operation = "takeAndComplete"
5903 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5904 output = self.distPrimitivesSend( cmdStr )
5905 if "Invalid operation name" in output:
5906 main.log.warn( output )
5907 return main.ERROR
5908 elif "Done" in output:
5909 return main.TRUE
5910 except TypeError:
5911 main.log.exception( self.name + ": Object not as expected" )
5912 return main.ERROR
5913 except Exception:
5914 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005915 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005916
5917 def workQueueDestroy( self, queueName ):
5918 """
5919 CLI command to destroy the specified Work Queue.
5920 This function uses the distributed primitives test app, which
5921 gives some cli access to distributed primitives for testing
5922 purposes only.
5923
5924 Required arguments:
5925 queueName - The name of the queue to add to
5926 returns:
5927 main.TRUE on success, main.FALSE on failure and
5928 main.ERROR on error.
5929 """
5930 try:
5931 queueName = str( queueName )
5932 prefix = "work-queue-test"
5933 operation = "destroy"
5934 cmdStr = " ".join( [ prefix, queueName, operation ] )
5935 output = self.distPrimitivesSend( cmdStr )
5936 if "Invalid operation name" in output:
5937 main.log.warn( output )
5938 return main.ERROR
5939 return main.TRUE
5940 except TypeError:
5941 main.log.exception( self.name + ": Object not as expected" )
5942 return main.ERROR
5943 except Exception:
5944 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005945 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005946
5947 def workQueueTotalPending( self, queueName ):
5948 """
5949 CLI command to get the Total Pending items of the specified Work Queue.
5950 This function uses the distributed primitives test app, which
5951 gives some cli access to distributed primitives for testing
5952 purposes only.
5953
5954 Required arguments:
5955 queueName - The name of the queue to add to
5956 returns:
5957 The number of Pending items in the specified work queue or
5958 None on error
5959 """
5960 try:
5961 queueName = str( queueName )
5962 prefix = "work-queue-test"
5963 operation = "totalPending"
5964 cmdStr = " ".join( [ prefix, queueName, operation ] )
5965 output = self.distPrimitivesSend( cmdStr )
5966 pattern = r'\d+'
5967 if "Invalid operation name" in output:
5968 main.log.warn( output )
5969 return None
5970 else:
5971 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005972 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005973 except ( AttributeError, TypeError ):
5974 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5975 return None
5976 except Exception:
5977 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005978 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005979
5980 def workQueueTotalCompleted( self, queueName ):
5981 """
5982 CLI command to get the Total Completed items of the specified Work Queue.
5983 This function uses the distributed primitives test app, which
5984 gives some cli access to distributed primitives for testing
5985 purposes only.
5986
5987 Required arguments:
5988 queueName - The name of the queue to add to
5989 returns:
5990 The number of complete items in the specified work queue or
5991 None on error
5992 """
5993 try:
5994 queueName = str( queueName )
5995 prefix = "work-queue-test"
5996 operation = "totalCompleted"
5997 cmdStr = " ".join( [ prefix, queueName, operation ] )
5998 output = self.distPrimitivesSend( cmdStr )
5999 pattern = r'\d+'
6000 if "Invalid operation name" in output:
6001 main.log.warn( output )
6002 return None
6003 else:
6004 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006005 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006006 except ( AttributeError, TypeError ):
6007 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6008 return None
6009 except Exception:
6010 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006011 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006012
6013 def workQueueTotalInProgress( self, queueName ):
6014 """
6015 CLI command to get the Total In Progress items of the specified Work Queue.
6016 This function uses the distributed primitives test app, which
6017 gives some cli access to distributed primitives for testing
6018 purposes only.
6019
6020 Required arguments:
6021 queueName - The name of the queue to add to
6022 returns:
6023 The number of In Progress items in the specified work queue or
6024 None on error
6025 """
6026 try:
6027 queueName = str( queueName )
6028 prefix = "work-queue-test"
6029 operation = "totalInProgress"
6030 cmdStr = " ".join( [ prefix, queueName, operation ] )
6031 output = self.distPrimitivesSend( cmdStr )
6032 pattern = r'\d+'
6033 if "Invalid operation name" in output:
6034 main.log.warn( output )
6035 return None
6036 else:
6037 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006038 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006039 except ( AttributeError, TypeError ):
6040 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6041 return None
6042 except Exception:
6043 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006044 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00006045
6046 def events( self, args='-a' ):
6047 """
6048 Description: Returns events -a command output
6049 Optional:
6050 add other arguments
6051 """
6052 try:
6053 cmdStr = "events"
6054 if args:
6055 cmdStr += " " + args
6056 handle = self.sendline( cmdStr )
6057 assert handle is not None, "Error in sendline"
6058 assert "Command not found:" not in handle, handle
6059 return handle
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!" )
6072 main.cleanAndExit()
6073
6074 def getMaster( self, deviceID ):
6075 """
6076 Description: Obtains current master using "roles" command for a specific deviceID
6077 """
6078 try:
6079 return str( self.getRole( deviceID )[ 'master' ] )
6080 except AssertionError:
6081 main.log.exception( "" )
6082 return None
6083 except TypeError:
6084 main.log.exception( self.name + ": Object not as expected" )
6085 return None
6086 except pexpect.EOF:
6087 main.log.error( self.name + ": EOF exception found" )
6088 main.log.error( self.name + ": " + self.handle.before )
6089 main.cleanAndExit()
6090 except Exception:
6091 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006092 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006093
6094 def issu( self ):
6095 """
6096 Short summary of In-Service Software Upgrade status
6097
6098 Returns the output of the cli command or None on Error
6099 """
6100 try:
6101 cmdStr = "issu"
6102 handle = self.sendline( cmdStr )
6103 assert handle is not None, "Error in sendline"
6104 assert "Command not found:" not in handle, handle
6105 assert "Unsupported command:" not in handle, handle
6106 return handle
6107 except AssertionError:
6108 main.log.exception( "" )
6109 return None
6110 except TypeError:
6111 main.log.exception( self.name + ": Object not as expected" )
6112 return None
6113 except pexpect.EOF:
6114 main.log.error( self.name + ": EOF exception found" )
6115 main.log.error( self.name + ": " + self.handle.before )
6116 main.cleanAndExit()
6117 except Exception:
6118 main.log.exception( self.name + ": Uncaught exception!" )
6119 main.cleanAndExit()
6120
6121 def issuInit( self ):
6122 """
6123 Initiates an In-Service Software Upgrade
6124
6125 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6126 """
6127 try:
6128 cmdStr = "issu init"
6129 handle = self.sendline( cmdStr )
6130 assert handle is not None, "Error in sendline"
6131 assert "Command not found:" not in handle, handle
6132 assert "Unsupported command:" not in handle, handle
6133 if "Initialized" in handle:
6134 return main.TRUE
6135 else:
6136 return main.FALSE
6137 except AssertionError:
6138 main.log.exception( "" )
6139 return main.ERROR
6140 except TypeError:
6141 main.log.exception( self.name + ": Object not as expected" )
6142 return main.ERROR
6143 except pexpect.EOF:
6144 main.log.error( self.name + ": EOF exception found" )
6145 main.log.error( self.name + ": " + self.handle.before )
6146 main.cleanAndExit()
6147 except Exception:
6148 main.log.exception( self.name + ": Uncaught exception!" )
6149 main.cleanAndExit()
6150
6151 def issuUpgrade( self ):
6152 """
6153 Transitions stores to upgraded nodes
6154
6155 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6156 """
6157 try:
6158 cmdStr = "issu upgrade"
6159 handle = self.sendline( cmdStr )
6160 assert handle is not None, "Error in sendline"
6161 assert "Command not found:" not in handle, handle
6162 assert "Unsupported command:" not in handle, handle
6163 if "Upgraded" in handle:
6164 return main.TRUE
6165 else:
6166 return main.FALSE
6167 except AssertionError:
6168 main.log.exception( "" )
6169 return main.ERROR
6170 except TypeError:
6171 main.log.exception( self.name + ": Object not as expected" )
6172 return main.ERROR
6173 except pexpect.EOF:
6174 main.log.error( self.name + ": EOF exception found" )
6175 main.log.error( self.name + ": " + self.handle.before )
6176 main.cleanAndExit()
6177 except Exception:
6178 main.log.exception( self.name + ": Uncaught exception!" )
6179 main.cleanAndExit()
6180
6181 def issuCommit( self ):
6182 """
6183 Finalizes an In-Service Software Upgrade
6184
6185 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6186 """
6187 try:
6188 cmdStr = "issu commit"
6189 handle = self.sendline( cmdStr )
6190 assert handle is not None, "Error in sendline"
6191 assert "Command not found:" not in handle, handle
6192 assert "Unsupported command:" not in handle, handle
6193 # TODO: Check the version returned by this command
6194 if "Committed version" in handle:
6195 return main.TRUE
6196 else:
6197 return main.FALSE
6198 except AssertionError:
6199 main.log.exception( "" )
6200 return main.ERROR
6201 except TypeError:
6202 main.log.exception( self.name + ": Object not as expected" )
6203 return main.ERROR
6204 except pexpect.EOF:
6205 main.log.error( self.name + ": EOF exception found" )
6206 main.log.error( self.name + ": " + self.handle.before )
6207 main.cleanAndExit()
6208 except Exception:
6209 main.log.exception( self.name + ": Uncaught exception!" )
6210 main.cleanAndExit()
6211
6212 def issuRollback( self ):
6213 """
6214 Rolls back an In-Service Software Upgrade
6215
6216 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6217 """
6218 try:
6219 cmdStr = "issu rollback"
6220 handle = self.sendline( cmdStr )
6221 assert handle is not None, "Error in sendline"
6222 assert "Command not found:" not in handle, handle
6223 assert "Unsupported command:" not in handle, handle
6224 # TODO: Check the version returned by this command
6225 if "Rolled back to version" in handle:
6226 return main.TRUE
6227 else:
6228 return main.FALSE
6229 except AssertionError:
6230 main.log.exception( "" )
6231 return main.ERROR
6232 except TypeError:
6233 main.log.exception( self.name + ": Object not as expected" )
6234 return main.ERROR
6235 except pexpect.EOF:
6236 main.log.error( self.name + ": EOF exception found" )
6237 main.log.error( self.name + ": " + self.handle.before )
6238 main.cleanAndExit()
6239 except Exception:
6240 main.log.exception( self.name + ": Uncaught exception!" )
6241 main.cleanAndExit()
6242
6243 def issuReset( self ):
6244 """
6245 Resets the In-Service Software Upgrade status after a rollback
6246
6247 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6248 """
6249 try:
6250 cmdStr = "issu reset"
6251 handle = self.sendline( cmdStr )
6252 assert handle is not None, "Error in sendline"
6253 assert "Command not found:" not in handle, handle
6254 assert "Unsupported command:" not in handle, handle
6255 # TODO: Check the version returned by this command
6256 if "Reset version" in handle:
6257 return main.TRUE
6258 else:
6259 return main.FALSE
6260 except AssertionError:
6261 main.log.exception( "" )
6262 return main.ERROR
6263 except TypeError:
6264 main.log.exception( self.name + ": Object not as expected" )
6265 return main.ERROR
6266 except pexpect.EOF:
6267 main.log.error( self.name + ": EOF exception found" )
6268 main.log.error( self.name + ": " + self.handle.before )
6269 main.cleanAndExit()
6270 except Exception:
6271 main.log.exception( self.name + ": Uncaught exception!" )
6272 main.cleanAndExit()
6273
6274 def issuStatus( self ):
6275 """
6276 Status of an In-Service Software Upgrade
6277
6278 Returns the output of the cli command or None on Error
6279 """
6280 try:
6281 cmdStr = "issu status"
6282 handle = self.sendline( cmdStr )
6283 assert handle is not None, "Error in sendline"
6284 assert "Command not found:" not in handle, handle
6285 assert "Unsupported command:" not in handle, handle
6286 return handle
6287 except AssertionError:
6288 main.log.exception( "" )
6289 return None
6290 except TypeError:
6291 main.log.exception( self.name + ": Object not as expected" )
6292 return None
6293 except pexpect.EOF:
6294 main.log.error( self.name + ": EOF exception found" )
6295 main.log.error( self.name + ": " + self.handle.before )
6296 main.cleanAndExit()
6297 except Exception:
6298 main.log.exception( self.name + ": Uncaught exception!" )
6299 main.cleanAndExit()
6300
6301 def issuVersion( self ):
6302 """
6303 Get the version of an In-Service Software Upgrade
6304
6305 Returns the output of the cli command or None on Error
6306 """
6307 try:
6308 cmdStr = "issu version"
6309 handle = self.sendline( cmdStr )
6310 assert handle is not None, "Error in sendline"
6311 assert "Command not found:" not in handle, handle
6312 assert "Unsupported command:" not in handle, handle
6313 return handle
6314 except AssertionError:
6315 main.log.exception( "" )
6316 return None
6317 except TypeError:
6318 main.log.exception( self.name + ": Object not as expected" )
6319 return None
6320 except pexpect.EOF:
6321 main.log.error( self.name + ": EOF exception found" )
6322 main.log.error( self.name + ": " + self.handle.before )
6323 main.cleanAndExit()
6324 except Exception:
6325 main.log.exception( self.name + ": Uncaught exception!" )
6326 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006327
6328 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6329 """
6330 Create a multicast route by calling 'mcast-join' command
6331 sIP: source IP of the multicast route
6332 groupIP: group IP of the multicast route
6333 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6334 dPorts: a list of destination ports of the multicast route
6335 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6336 """
6337 try:
6338 cmdStr = "mcast-join"
6339 cmdStr += " " + str( sIP )
6340 cmdStr += " " + str( groupIP )
6341 cmdStr += " " + str( sPort )
6342 assert isinstance( dPorts, list )
6343 for dPort in dPorts:
6344 cmdStr += " " + str( dPort )
6345 handle = self.sendline( cmdStr )
6346 assert handle is not None, "Error in sendline"
6347 assert "Command not found:" not in handle, handle
6348 assert "Unsupported command:" not in handle, handle
6349 assert "Error executing command" not in handle, handle
6350 if "Added the mcast route" in handle:
6351 return main.TRUE
6352 else:
6353 return main.FALSE
6354 except AssertionError:
6355 main.log.exception( "" )
6356 return None
6357 except TypeError:
6358 main.log.exception( self.name + ": Object not as expected" )
6359 return None
6360 except pexpect.EOF:
6361 main.log.error( self.name + ": EOF exception found" )
6362 main.log.error( self.name + ": " + self.handle.before )
6363 main.cleanAndExit()
6364 except Exception:
6365 main.log.exception( self.name + ": Uncaught exception!" )
6366 main.cleanAndExit()
6367
6368 def mcastDelete( self, sIP, groupIP, dPorts ):
6369 """
6370 Delete a multicast route by calling 'mcast-delete' command
6371 sIP: source IP of the multicast route
6372 groupIP: group IP of the multicast route
6373 dPorts: a list of destination ports of the multicast route
6374 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6375 """
6376 try:
6377 cmdStr = "mcast-delete"
6378 cmdStr += " " + str( sIP )
6379 cmdStr += " " + str( groupIP )
6380 assert isinstance( dPorts, list )
6381 for dPort in dPorts:
6382 cmdStr += " " + str( dPort )
6383 handle = self.sendline( cmdStr )
6384 assert handle is not None, "Error in sendline"
6385 assert "Command not found:" not in handle, handle
6386 assert "Unsupported command:" not in handle, handle
6387 assert "Error executing command" not in handle, handle
6388 if "Updated the mcast route" in handle:
6389 return main.TRUE
6390 else:
6391 return main.FALSE
6392 except AssertionError:
6393 main.log.exception( "" )
6394 return None
6395 except TypeError:
6396 main.log.exception( self.name + ": Object not as expected" )
6397 return None
6398 except pexpect.EOF:
6399 main.log.error( self.name + ": EOF exception found" )
6400 main.log.error( self.name + ": " + self.handle.before )
6401 main.cleanAndExit()
6402 except Exception:
6403 main.log.exception( self.name + ": Uncaught exception!" )
6404 main.cleanAndExit()
6405
6406 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6407 """
6408 Create a multicast route by calling 'mcast-host-join' command
6409 sAddr: we can provide * for ASM or a specific address for SSM
6410 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006411 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006412 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6413 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6414 """
6415 try:
6416 cmdStr = "mcast-host-join"
6417 cmdStr += " -sAddr " + str( sAddr )
6418 cmdStr += " -gAddr " + str( gAddr )
6419 assert isinstance( srcs, list )
6420 for src in srcs:
6421 cmdStr += " -srcs " + str( src )
6422 assert isinstance( sinks, list )
6423 for sink in sinks:
6424 cmdStr += " -sinks " + str( sink )
6425 handle = self.sendline( cmdStr )
6426 assert handle is not None, "Error in sendline"
6427 assert "Command not found:" not in handle, handle
6428 assert "Unsupported command:" not in handle, handle
6429 assert "Error executing command" not in handle, handle
6430 if "Added the mcast route" in handle:
6431 return main.TRUE
6432 else:
6433 return main.FALSE
6434 except AssertionError:
6435 main.log.exception( "" )
6436 return None
6437 except TypeError:
6438 main.log.exception( self.name + ": Object not as expected" )
6439 return None
6440 except pexpect.EOF:
6441 main.log.error( self.name + ": EOF exception found" )
6442 main.log.error( self.name + ": " + self.handle.before )
6443 main.cleanAndExit()
6444 except Exception:
6445 main.log.exception( self.name + ": Uncaught exception!" )
6446 main.cleanAndExit()
6447
6448 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6449 """
6450 Delete multicast sink(s) by calling 'mcast-host-delete' command
6451 sAddr: we can provide * for ASM or a specific address for SSM
6452 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006453 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006454 will delete the route if not specified
6455 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6456 """
6457 try:
6458 cmdStr = "mcast-host-delete"
6459 cmdStr += " -sAddr " + str( sAddr )
6460 cmdStr += " -gAddr " + str( gAddr )
6461 if host:
6462 cmdStr += " -h " + str( host )
6463 handle = self.sendline( cmdStr )
6464 assert handle is not None, "Error in sendline"
6465 assert "Command not found:" not in handle, handle
6466 assert "Unsupported command:" not in handle, handle
6467 assert "Error executing command" not in handle, handle
6468 if "Updated the mcast route" in handle:
6469 return main.TRUE
6470 elif "Deleted the mcast route" in handle:
6471 return main.TRUE
6472 else:
6473 return main.FALSE
6474 except AssertionError:
6475 main.log.exception( "" )
6476 return None
6477 except TypeError:
6478 main.log.exception( self.name + ": Object not as expected" )
6479 return None
6480 except pexpect.EOF:
6481 main.log.error( self.name + ": EOF exception found" )
6482 main.log.error( self.name + ": " + self.handle.before )
6483 main.cleanAndExit()
6484 except Exception:
6485 main.log.exception( self.name + ": Uncaught exception!" )
6486 main.cleanAndExit()
6487
You Wang547893e2018-05-08 13:34:59 -07006488 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6489 """
6490 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6491 sAddr: we can provide * for ASM or a specific address for SSM
6492 gAddr: specifies multicast group address
6493 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6494 will delete the route if not specified
6495 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6496 """
6497 try:
6498 cmdStr = "mcast-sink-delete"
6499 cmdStr += " -sAddr " + str( sAddr )
6500 cmdStr += " -gAddr " + str( gAddr )
6501 if sink:
6502 cmdStr += " -s " + str( sink )
6503 handle = self.sendline( cmdStr )
6504 assert handle is not None, "Error in sendline"
6505 assert "Command not found:" not in handle, handle
6506 assert "Unsupported command:" not in handle, handle
6507 assert "Error executing command" not in handle, handle
6508 if "Updated the mcast route" in handle:
6509 return main.TRUE
6510 elif "Deleted the mcast route" in handle:
6511 return main.TRUE
6512 else:
6513 return main.FALSE
6514 except AssertionError:
6515 main.log.exception( "" )
6516 return None
6517 except TypeError:
6518 main.log.exception( self.name + ": Object not as expected" )
6519 return None
6520 except pexpect.EOF:
6521 main.log.error( self.name + ": EOF exception found" )
6522 main.log.error( self.name + ": " + self.handle.before )
6523 main.cleanAndExit()
6524 except Exception:
6525 main.log.exception( self.name + ": Uncaught exception!" )
6526 main.cleanAndExit()
6527
You Wange24d6272018-03-27 21:18:50 -07006528 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6529 """
6530 Delete multicast src(s) by calling 'mcast-source-delete' command
6531 sAddr: we can provide * for ASM or a specific address for SSM
6532 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006533 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 -07006534 will delete the route if not specified
6535 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6536 """
6537 try:
6538 cmdStr = "mcast-source-delete"
6539 cmdStr += " -sAddr " + str( sAddr )
6540 cmdStr += " -gAddr " + str( gAddr )
6541 if srcs:
6542 assert isinstance( srcs, list )
6543 for src in srcs:
6544 cmdStr += " -src " + str( src )
6545 handle = self.sendline( cmdStr )
6546 assert handle is not None, "Error in sendline"
6547 assert "Command not found:" not in handle, handle
6548 assert "Unsupported command:" not in handle, handle
6549 assert "Error executing command" not in handle, handle
6550 if "Updated the mcast route" in handle:
6551 return main.TRUE
6552 elif "Deleted the mcast route" in handle:
6553 return main.TRUE
6554 else:
6555 return main.FALSE
6556 except AssertionError:
6557 main.log.exception( "" )
6558 return None
6559 except TypeError:
6560 main.log.exception( self.name + ": Object not as expected" )
6561 return None
6562 except pexpect.EOF:
6563 main.log.error( self.name + ": EOF exception found" )
6564 main.log.error( self.name + ": " + self.handle.before )
6565 main.cleanAndExit()
6566 except Exception:
6567 main.log.exception( self.name + ": Uncaught exception!" )
6568 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006569
6570 def netcfg( self, jsonFormat=True, args="" ):
6571 """
6572 Run netcfg cli command with given args
6573 """
6574 try:
6575 cmdStr = "netcfg"
6576 if jsonFormat:
6577 cmdStr = cmdStr + " -j"
6578 if args:
6579 cmdStr = cmdStr + " " + str( args )
6580 handle = self.sendline( cmdStr )
6581 assert handle is not None, "Error in sendline"
6582 assert "Command not found:" not in handle, handle
6583 assert "Unsupported command:" not in handle, handle
6584 assert "Error executing command" not in handle, handle
6585 return handle
6586 except AssertionError:
6587 main.log.exception( "" )
6588 return None
6589 except TypeError:
6590 main.log.exception( self.name + ": Object not as expected" )
6591 return None
6592 except pexpect.EOF:
6593 main.log.error( self.name + ": EOF exception found" )
6594 main.log.error( self.name + ": " + self.handle.before )
6595 main.cleanAndExit()
6596 except Exception:
6597 main.log.exception( self.name + ": Uncaught exception!" )
6598 main.cleanAndExit()
6599
You Wang0fa76e72018-05-18 11:33:25 -07006600 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006601 """
You Wang54b1d672018-06-11 16:44:13 -07006602 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006603 Options:
6604 sAddr: IP address of the source host
6605 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006606 ipv6: True if hosts are IPv6
6607 verbose: return verbose t3 output if True
6608 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006609 """
6610 try:
6611 # Collect information of both hosts from onos
6612 hosts = self.hosts()
6613 hosts = json.loads( hosts )
6614 sHost = None
6615 dHost = None
6616 for host in hosts:
6617 if sAddr in host[ "ipAddresses" ]:
6618 sHost = host
6619 elif dAddr in host[ "ipAddresses" ]:
6620 dHost = host
6621 if sHost and dHost:
6622 break
6623 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006624 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006625 if simple:
6626 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006627 cmdStr = "t3-troubleshoot-simple"
6628 if verbose:
6629 cmdStr += " -vv"
6630 if ipv6:
6631 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006632 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006633 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006634 else:
You Wang54b1d672018-06-11 16:44:13 -07006635 for location in sHost[ "locations" ]:
6636 cmdStr = "t3-troubleshoot"
6637 if verbose:
6638 cmdStr += " -vv"
6639 if ipv6:
6640 cmdStr += " -et ipv6"
6641 cmdStr += " -s " + str( sAddr )
6642 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6643 cmdStr += " -sm " + str( sHost[ "mac" ] )
6644 if sHost[ "vlan" ] != "None":
6645 cmdStr += " -vid " + sHost[ "vlan" ]
6646 cmdStr += " -d " + str( dAddr )
6647 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6648 netcfg = json.loads( netcfg )
6649 assert netcfg, "Failed to get netcfg"
6650 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6651 cmdList.append( cmdStr )
6652 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006653 except AssertionError:
6654 main.log.exception( "" )
6655 return None
6656 except ( KeyError, TypeError ):
6657 main.log.exception( self.name + ": Object not as expected" )
6658 return None
6659 except Exception:
6660 main.log.exception( self.name + ": Uncaught exception!" )
6661 main.cleanAndExit()
6662
6663 def t3( self, sAddr, dAddr, ipv6=False ):
6664 """
You Wang54b1d672018-06-11 16:44:13 -07006665 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006666 Options:
6667 sAddr: IP address of the source host
6668 dAddr: IP address of the destination host
6669 """
6670 try:
You Wang54b1d672018-06-11 16:44:13 -07006671 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6672 assert cmdList is not None, "composeT3Command returned None"
6673 t3Output = ""
6674 for cmdStr in cmdList:
6675 handle = self.sendline( cmdStr )
6676 assert handle is not None, "Error in sendline"
6677 assert "Command not found:" not in handle, handle
6678 assert "Unsupported command:" not in handle, handle
6679 assert "Error executing command" not in handle, handle
6680 assert "Tracing packet" in handle
6681 t3Output += handle
6682 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006683 except AssertionError:
6684 main.log.exception( "" )
6685 return None
6686 except pexpect.EOF:
6687 main.log.error( self.name + ": EOF exception found" )
6688 main.log.error( self.name + ": " + self.handle.before )
6689 main.cleanAndExit()
6690 except Exception:
6691 main.log.exception( self.name + ": Uncaught exception!" )
6692 main.cleanAndExit()