blob: 033ba875763fa67c4ed6e00a4d587fce8f4a564f [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 Hallcf31d0f2018-12-13 11:18:48 -0800561 karafEscape = re.compile( r"('(0|1)~\'|\r\r\r\n\x1b\[A\x1b\[79C(x|\s)?|\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
Jon Hallcf31d0f2018-12-13 11:18:48 -0800574 # NOTE: karaf is sometimes adding a single character then two
575 # backspaces and sometimes adding 2 characters with 2 backspaces??
Jon Hall6c9e2da2018-11-06 12:01:23 -0800576 backspaceEscape = re.compile( r'((..\x08\x08)|(.|\s)\x08)' )
577 response = backspaceEscape.sub( '', response )
578 if debug:
579 main.log.debug( self.name + ": backspaceEscape output" )
580 main.log.debug( self.name + ": " + repr( response ) )
581
kelvin-onlabfb521662015-02-27 09:52:40 -0800582 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000583 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700584 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700585 main.log.debug( self.name + ": Removed extra returns " +
586 "from output" )
587 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700588
589 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800590 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700591 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700592 main.log.debug( self.name + ": parsed and stripped output" )
593 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700594
Jon Hall63604932015-02-26 17:09:50 -0800595 # parse for just the output, remove the cmd from response
Jon Hallce0d70b2018-12-11 11:01:32 -0800596 cmdPattern = cmdStr.strip()
597 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
598 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800599 if relaxedRegex:
Jon Hallce0d70b2018-12-11 11:01:32 -0800600 cmdPattern = cmdPattern.split( '|' )[ -1 ].strip()
601 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
602 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800603 # This was added because karaf 4.2 is stripping some characters from the command echo
Jon Hallce0d70b2018-12-11 11:01:32 -0800604 output = response.split( cmdPattern, 1 )
Jon Hall39e3ffe2018-12-05 11:40:29 -0800605 if len( output ) < 2:
606 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800607 cmdPattern = cmdPattern[ -5: ]
608 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
609 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
610 output = response.split( cmdPattern, 1 )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800611 else:
Jon Hallce0d70b2018-12-11 11:01:32 -0800612 output = response.split( cmdPattern, 1 )
613 if len( output ) < 2: # TODO: Should we do this without the relaxedRegex flag?
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800614 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800615 output = response.split( cmdPattern[ -5: ], 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700616 if output:
617 if debug:
618 main.log.debug( self.name + ": split output" )
619 for r in output:
620 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallce0d70b2018-12-11 11:01:32 -0800621 if len( output ) == 1:
622 main.log.error( "Could not remove sent command echo from output" )
623 return output
Jon Hall0e240372018-05-02 11:21:57 -0700624 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800625 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800626 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700627 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800628 return output
GlennRCed771242016-01-13 17:02:47 -0800629 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700630 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800631 if debug:
632 main.log.debug( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700633 self.handle.send( "\x03" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800634 self.handle.expect( self.karafPrompt )
GlennRCed771242016-01-13 17:02:47 -0800635 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700636 except IndexError:
637 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700638 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700639 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800640 except TypeError:
641 main.log.exception( self.name + ": Object not as expected" )
642 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400643 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800644 main.log.error( self.name + ": EOF exception found" )
645 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700646 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700647 return None
648 else:
Devin Lim44075962017-08-11 10:56:37 -0700649 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800650 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800651 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700652 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700653 return None
654 else:
Devin Lim44075962017-08-11 10:56:37 -0700655 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400656
Jon Halld5a94fb2018-11-13 14:32:23 -0800657 def lineCount( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True ):
658 """
659 A wrapper around sendline(). Will return the number of lines returned or None on error
660
661 Required Arguments:
662 cmdStr - String to send to the pexpect session
663
664 Optional Arguments:
665 showResponse - Defaults to False. If True will log the response.
666 debug - Defaults to False. If True, will enable debug logging.
667 timeout - Defaults to 10. Amount of time in seconds for a command to return
668 before a timeout.
669 noExit - Defaults to False. If True, will not exit TestON in the event of a
670 closed channel, but instead return None
671 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.
672
673 Warning: There are no sanity checking to commands sent using this method.
674
675 """
676 try:
677 numLines = self.sendline( cmdStr, showResponse, debug, timeout, noExit, relaxedRegex )
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800678 parsed = re.search( "(\d+)\s+(\d+)", numLines )
679 if not parsed:
680 main.log.error( "Warning, output of karaf's wc may have changed" )
681 return None
682 return parsed.group( 1 )
Jon Halld5a94fb2018-11-13 14:32:23 -0800683 except IndexError:
684 main.log.exception( self.name + ": Object not as expected" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800685 main.log.debug( "response: {}".format( repr( numLines ) ) )
Jon Halld5a94fb2018-11-13 14:32:23 -0800686 return None
687 except TypeError:
688 main.log.exception( self.name + ": Object not as expected" )
689 return None
690 except Exception:
691 main.log.exception( self.name + ": Uncaught exception!" )
692 if noExit:
693 return None
694 else:
695 main.cleanAndExit()
696
kelvin8ec71442015-01-15 16:57:00 -0800697 # IMPORTANT NOTE:
698 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800699 # the cli command changing 'a:b' with 'aB'.
700 # Ex ) onos:topology > onosTopology
701 # onos:links > onosLinks
702 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800703
kelvin-onlabd3b64892015-01-20 13:26:24 -0800704 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800705 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400706 Adds a new cluster node by ID and address information.
707 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800708 * nodeId
709 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400710 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800711 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800712 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400713 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800714 cmdStr = "add-node " + str( nodeId ) + " " +\
715 str( ONOSIp ) + " " + str( tcpPort )
716 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700717 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800718 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800719 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700720 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800721 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800722 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400723 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800724 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400725 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800726 except AssertionError:
727 main.log.exception( "" )
728 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800729 except TypeError:
730 main.log.exception( self.name + ": Object not as expected" )
731 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400732 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800733 main.log.error( self.name + ": EOF exception found" )
734 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700735 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800736 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800737 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700738 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400739
kelvin-onlabd3b64892015-01-20 13:26:24 -0800740 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800741 """
andrewonlab86dc3082014-10-13 18:18:38 -0400742 Removes a cluster by ID
743 Issues command: 'remove-node [<node-id>]'
744 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800745 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800746 """
andrewonlab86dc3082014-10-13 18:18:38 -0400747 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400748
kelvin-onlabd3b64892015-01-20 13:26:24 -0800749 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700750 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700751 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800752 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700753 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700754 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700755 main.log.error( handle )
756 return main.FALSE
757 else:
758 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800759 except AssertionError:
760 main.log.exception( "" )
761 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800762 except TypeError:
763 main.log.exception( self.name + ": Object not as expected" )
764 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400765 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800766 main.log.error( self.name + ": EOF exception found" )
767 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700768 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800769 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800770 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700771 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400772
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700773 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800774 """
andrewonlab7c211572014-10-15 16:45:20 -0400775 List the nodes currently visible
776 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700777 Optional argument:
778 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800779 """
andrewonlab7c211572014-10-15 16:45:20 -0400780 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700781 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700782 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700783 cmdStr += " -j"
784 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700785 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800786 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700787 return output
Jon Hallc6793552016-01-19 14:18:37 -0800788 except AssertionError:
789 main.log.exception( "" )
790 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800791 except TypeError:
792 main.log.exception( self.name + ": Object not as expected" )
793 return None
andrewonlab7c211572014-10-15 16:45:20 -0400794 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800795 main.log.error( self.name + ": EOF exception found" )
796 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700797 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800798 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800799 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700800 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400801
kelvin8ec71442015-01-15 16:57:00 -0800802 def topology( self ):
803 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700804 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700805 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700806 Return:
807 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800808 """
andrewonlab95ce8322014-10-13 14:12:04 -0400809 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700810 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800811 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800812 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800813 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700814 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400815 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800816 except AssertionError:
817 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800818 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800819 except TypeError:
820 main.log.exception( self.name + ": Object not as expected" )
821 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400822 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800823 main.log.error( self.name + ": EOF exception found" )
824 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700825 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800826 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800827 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700828 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800829
jenkins7ead5a82015-03-13 10:28:21 -0700830 def deviceRemove( self, deviceId ):
831 """
832 Removes particular device from storage
833
834 TODO: refactor this function
835 """
836 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700837 cmdStr = "device-remove " + str( deviceId )
838 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800839 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800840 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700841 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700842 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700843 main.log.error( handle )
844 return main.FALSE
845 else:
846 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800847 except AssertionError:
848 main.log.exception( "" )
849 return None
jenkins7ead5a82015-03-13 10:28:21 -0700850 except TypeError:
851 main.log.exception( self.name + ": Object not as expected" )
852 return None
853 except pexpect.EOF:
854 main.log.error( self.name + ": EOF exception found" )
855 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700856 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700857 except Exception:
858 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700859 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700860
You Wang3b9689a2018-08-30 12:24:00 -0700861 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800862 """
Jon Hall7b02d952014-10-17 20:14:54 -0400863 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400864 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800865 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800866 """
andrewonlab86dc3082014-10-13 18:18:38 -0400867 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700868 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800869 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700870 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700871 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800872 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800873 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700874 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800875 except AssertionError:
876 main.log.exception( "" )
877 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800878 except TypeError:
879 main.log.exception( self.name + ": Object not as expected" )
880 return None
andrewonlab7c211572014-10-15 16:45:20 -0400881 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800882 main.log.error( self.name + ": EOF exception found" )
883 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700884 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800885 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800886 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700887 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400888
kelvin-onlabd3b64892015-01-20 13:26:24 -0800889 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800890 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800891 This balances the devices across all controllers
892 by issuing command: 'onos> onos:balance-masters'
893 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800894 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800895 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700897 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800898 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800899 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700900 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700901 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700902 main.log.error( handle )
903 return main.FALSE
904 else:
905 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800906 except AssertionError:
907 main.log.exception( "" )
908 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800909 except TypeError:
910 main.log.exception( self.name + ": Object not as expected" )
911 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800912 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800913 main.log.error( self.name + ": EOF exception found" )
914 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700915 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800916 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800917 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700918 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800919
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000920 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700921 """
922 Returns the output of the masters command.
923 Optional argument:
924 * jsonFormat - boolean indicating if you want output in json
925 """
926 try:
927 cmdStr = "onos:masters"
928 if jsonFormat:
929 cmdStr += " -j"
930 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700931 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800932 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700933 return output
Jon Hallc6793552016-01-19 14:18:37 -0800934 except AssertionError:
935 main.log.exception( "" )
936 return None
acsmars24950022015-07-30 18:00:43 -0700937 except TypeError:
938 main.log.exception( self.name + ": Object not as expected" )
939 return None
940 except pexpect.EOF:
941 main.log.error( self.name + ": EOF exception found" )
942 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700943 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700944 except Exception:
945 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700946 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700947
Jon Hallc6793552016-01-19 14:18:37 -0800948 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700949 """
950 Uses the master command to check that the devices' leadership
951 is evenly divided
952
953 Dependencies: checkMasters() and summary()
954
Jon Hall6509dbf2016-06-21 17:01:17 -0700955 Returns main.TRUE if the devices are balanced
956 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700957 Exits on Exception
958 Returns None on TypeError
959 """
960 try:
Jon Hallc6793552016-01-19 14:18:37 -0800961 summaryOutput = self.summary()
962 totalDevices = json.loads( summaryOutput )[ "devices" ]
963 except ( TypeError, ValueError ):
964 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
965 return None
966 try:
acsmars24950022015-07-30 18:00:43 -0700967 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800968 mastersOutput = self.checkMasters()
969 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700970 first = masters[ 0 ][ "size" ]
971 for master in masters:
972 totalOwnedDevices += master[ "size" ]
973 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
974 main.log.error( "Mastership not balanced" )
975 main.log.info( "\n" + self.checkMasters( False ) )
976 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700977 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700978 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700979 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800980 except ( TypeError, ValueError ):
981 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700982 return None
983 except pexpect.EOF:
984 main.log.error( self.name + ": EOF exception found" )
985 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700986 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700987 except Exception:
988 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700989 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700990
YPZhangfebf7302016-05-24 16:45:56 -0700991 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800992 """
Jon Halle8217482014-10-17 13:49:14 -0400993 Lists all core links
994 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800995 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800996 """
Jon Halle8217482014-10-17 13:49:14 -0400997 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700998 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800999 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001000 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07001001 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001002 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001003 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001004 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001005 except AssertionError:
1006 main.log.exception( "" )
1007 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001008 except TypeError:
1009 main.log.exception( self.name + ": Object not as expected" )
1010 return None
Jon Halle8217482014-10-17 13:49:14 -04001011 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001012 main.log.error( self.name + ": EOF exception found" )
1013 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001014 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001015 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001016 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001017 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001018
You Wang3b9689a2018-08-30 12:24:00 -07001019 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001020 """
Jon Halle8217482014-10-17 13:49:14 -04001021 Lists all ports
1022 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001023 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001024 """
Jon Halle8217482014-10-17 13:49:14 -04001025 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001026 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001027 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001028 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -07001029 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001030 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001031 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001032 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001033 except AssertionError:
1034 main.log.exception( "" )
1035 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001036 except TypeError:
1037 main.log.exception( self.name + ": Object not as expected" )
1038 return None
Jon Halle8217482014-10-17 13:49:14 -04001039 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001040 main.log.error( self.name + ": EOF exception found" )
1041 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001042 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001043 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001044 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001045 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001046
kelvin-onlabd3b64892015-01-20 13:26:24 -08001047 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001048 """
Jon Hall983a1702014-10-28 18:44:22 -04001049 Lists all devices and the controllers with roles assigned to them
1050 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001051 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001052 """
andrewonlab7c211572014-10-15 16:45:20 -04001053 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001054 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001055 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001056 cmdStr += " -j"
1057 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001058 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001059 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001060 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001061 except AssertionError:
1062 main.log.exception( "" )
1063 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001064 except TypeError:
1065 main.log.exception( self.name + ": Object not as expected" )
1066 return None
Jon Hall983a1702014-10-28 18:44:22 -04001067 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001068 main.log.error( self.name + ": EOF exception found" )
1069 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001070 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001071 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001072 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001073 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -04001074
kelvin-onlabd3b64892015-01-20 13:26:24 -08001075 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001076 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001077 Given the a string containing the json representation of the "roles"
1078 cli command and a partial or whole device id, returns a json object
1079 containing the roles output for the first device whose id contains
1080 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001081
1082 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001083 A dict of the role assignments for the given device or
1084 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001085 """
Jon Hall983a1702014-10-28 18:44:22 -04001086 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001087 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001088 return None
1089 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001090 rawRoles = self.roles()
1091 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001092 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001094 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001095 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001096 return device
1097 return None
Jon Hallc6793552016-01-19 14:18:37 -08001098 except ( TypeError, ValueError ):
1099 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001100 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001101 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001102 main.log.error( self.name + ": EOF exception found" )
1103 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001104 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001105 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001106 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001107 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001108
kelvin-onlabd3b64892015-01-20 13:26:24 -08001109 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001110 """
Jon Hall94fd0472014-12-08 11:52:42 -08001111 Iterates through each device and checks if there is a master assigned
1112 Returns: main.TRUE if each device has a master
1113 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001114 """
Jon Hall94fd0472014-12-08 11:52:42 -08001115 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001116 rawRoles = self.roles()
1117 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001118 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001120 # print device
1121 if device[ 'master' ] == "none":
1122 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001123 return main.FALSE
1124 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001125 except ( TypeError, ValueError ):
1126 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001127 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001128 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001129 main.log.error( self.name + ": EOF exception found" )
1130 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001131 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001132 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001133 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001134 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001135
kelvin-onlabd3b64892015-01-20 13:26:24 -08001136 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001137 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001138 Returns string of paths, and the cost.
1139 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001140 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001141 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001142 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1143 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001144 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001145 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001146 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001147 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001148 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001149 else:
kelvin8ec71442015-01-15 16:57:00 -08001150 path = handle.split( ";" )[ 0 ]
1151 cost = handle.split( ";" )[ 1 ]
1152 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001153 except AssertionError:
1154 main.log.exception( "" )
1155 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001156 except TypeError:
1157 main.log.exception( self.name + ": Object not as expected" )
1158 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001159 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001160 main.log.error( self.name + ": EOF exception found" )
1161 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001162 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001163 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001164 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001165 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001166
kelvin-onlabd3b64892015-01-20 13:26:24 -08001167 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001168 """
Jon Hallffb386d2014-11-21 13:43:38 -08001169 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001170 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001171 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001172 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001173 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001174 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001175 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001176 cmdStr += " -j"
1177 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001178 if handle:
1179 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001180 # TODO: Maybe make this less hardcoded
1181 # ConsistentMap Exceptions
1182 assert "org.onosproject.store.service" not in handle
1183 # Node not leader
1184 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001185 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001186 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001187 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001188 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001189 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001190 except TypeError:
1191 main.log.exception( self.name + ": Object not as expected" )
1192 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001193 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001194 main.log.error( self.name + ": EOF exception found" )
1195 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001196 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001197 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001198 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001199 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001200
kelvin-onlabd3b64892015-01-20 13:26:24 -08001201 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001202 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001203 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001204
Jon Hallefbd9792015-03-05 16:11:36 -08001205 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001206 partial mac address
1207
Jon Hall42db6dc2014-10-24 19:03:48 -04001208 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001209 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001210 try:
kelvin8ec71442015-01-15 16:57:00 -08001211 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001212 return None
1213 else:
1214 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001215 rawHosts = self.hosts()
1216 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001217 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001218 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001219 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001220 if not host:
1221 pass
1222 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001223 return host
1224 return None
Jon Hallc6793552016-01-19 14:18:37 -08001225 except ( TypeError, ValueError ):
1226 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001227 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001228 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001229 main.log.error( self.name + ": EOF exception found" )
1230 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001231 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001232 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001233 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001234 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001235
kelvin-onlabd3b64892015-01-20 13:26:24 -08001236 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001237 """
1238 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001239 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001240
andrewonlab3f0a4af2014-10-17 12:25:14 -04001241 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001242 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001243 IMPORTANT:
1244 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001245 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001246 Furthermore, it assumes that value of VLAN is '-1'
1247 Description:
kelvin8ec71442015-01-15 16:57:00 -08001248 Converts mininet hosts ( h1, h2, h3... ) into
1249 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1250 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001251 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001252 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001253
kelvin-onlabd3b64892015-01-20 13:26:24 -08001254 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001255 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001256 hostHex = hex( int( host ) ).zfill( 12 )
1257 hostHex = str( hostHex ).replace( 'x', '0' )
1258 i = iter( str( hostHex ) )
1259 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1260 hostHex = hostHex + "/-1"
1261 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001262
kelvin-onlabd3b64892015-01-20 13:26:24 -08001263 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001264
Jon Halld4d4b372015-01-28 16:02:41 -08001265 except TypeError:
1266 main.log.exception( self.name + ": Object not as expected" )
1267 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001268 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001269 main.log.error( self.name + ": EOF exception found" )
1270 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001271 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001272 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001273 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001274 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001275
You Wangbc898b82018-05-03 16:22:34 -07001276 def verifyHostLocation( self, hostIp, location ):
1277 """
1278 Description:
1279 Verify the host given is discovered in all locations expected
1280 Required:
1281 hostIp: IP address of the host
1282 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1283 Could be a string or list
1284 Returns:
1285 main.TRUE if host is discovered on all locations provided
1286 main.FALSE otherwise
1287 """
1288 import json
1289 locations = [ location ] if isinstance( location, str ) else location
1290 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1291 try:
1292 hosts = self.hosts()
1293 hosts = json.loads( hosts )
1294 targetHost = None
1295 for host in hosts:
1296 if hostIp in host[ "ipAddresses" ]:
1297 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001298 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001299 result = main.TRUE
1300 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1301 for loc in locations:
1302 discovered = False
1303 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001304 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1305 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001306 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001307 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001308 break
1309 if discovered:
1310 locationsDiscovered.remove( locDiscovered )
1311 else:
1312 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1313 result = main.FALSE
1314 if locationsDiscovered:
1315 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1316 result = main.FALSE
1317 return result
1318 except KeyError:
1319 main.log.exception( self.name + ": host data not as expected: " + hosts )
1320 return None
1321 except pexpect.EOF:
1322 main.log.error( self.name + ": EOF exception found" )
1323 main.log.error( self.name + ": " + self.handle.before )
1324 main.cleanAndExit()
1325 except Exception:
1326 main.log.exception( self.name + ": Uncaught exception" )
1327 return None
1328
You Wang53dba1e2018-02-02 17:45:44 -08001329 def verifyHostIp( self, hostList=[], prefix="" ):
1330 """
1331 Description:
1332 Verify that all hosts have IP address assigned to them
1333 Optional:
1334 hostList: If specified, verifications only happen to the hosts
1335 in hostList
1336 prefix: at least one of the ip address assigned to the host
1337 needs to have the specified prefix
1338 Returns:
1339 main.TRUE if all hosts have specific IP address assigned;
1340 main.FALSE otherwise
1341 """
1342 import json
1343 try:
1344 hosts = self.hosts()
1345 hosts = json.loads( hosts )
1346 if not hostList:
1347 hostList = [ host[ "id" ] for host in hosts ]
1348 for host in hosts:
1349 hostId = host[ "id" ]
1350 if hostId not in hostList:
1351 continue
1352 ipList = host[ "ipAddresses" ]
1353 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1354 if not ipList:
1355 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1356 else:
1357 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1358 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1359 else:
1360 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1361 hostList.remove( hostId )
1362 if hostList:
1363 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1364 return main.FALSE
1365 else:
1366 return main.TRUE
1367 except KeyError:
1368 main.log.exception( self.name + ": host data not as expected: " + hosts )
1369 return None
1370 except pexpect.EOF:
1371 main.log.error( self.name + ": EOF exception found" )
1372 main.log.error( self.name + ": " + self.handle.before )
1373 main.cleanAndExit()
1374 except Exception:
1375 main.log.exception( self.name + ": Uncaught exception" )
1376 return None
1377
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001378 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001379 """
andrewonlabe6745342014-10-17 14:29:13 -04001380 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001381 * hostIdOne: ONOS host id for host1
1382 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001383 Optional:
1384 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001385 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001386 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001387 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001388 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001389 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001390 Returns:
1391 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001392 """
andrewonlabe6745342014-10-17 14:29:13 -04001393 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001394 cmdStr = "add-host-intent "
1395 if vlanId:
1396 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001397 if setVlan:
1398 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001399 if encap:
1400 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001401 if bandwidth:
1402 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001403 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001404 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001405 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001406 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001407 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001408 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001409 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001410 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001411 else:
1412 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001413 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001414 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001415 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001416 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001417 else:
1418 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001419 main.log.debug( "Response from ONOS was: " +
1420 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001421 return None
Jon Hallc6793552016-01-19 14:18:37 -08001422 except AssertionError:
1423 main.log.exception( "" )
1424 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001425 except TypeError:
1426 main.log.exception( self.name + ": Object not as expected" )
1427 return None
andrewonlabe6745342014-10-17 14:29:13 -04001428 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001429 main.log.error( self.name + ": EOF exception found" )
1430 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001431 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001432 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001433 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001434 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001435
kelvin-onlabd3b64892015-01-20 13:26:24 -08001436 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001437 """
andrewonlab7b31d232014-10-24 13:31:47 -04001438 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001439 * ingressDevice: device id of ingress device
1440 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001441 Optional:
1442 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001443 Description:
1444 Adds an optical intent by specifying an ingress and egress device
1445 Returns:
1446 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001447 """
andrewonlab7b31d232014-10-24 13:31:47 -04001448 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001449 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1450 " " + str( egressDevice )
1451 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001452 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001453 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001454 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001455 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001456 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001457 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001458 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001459 main.log.info( "Optical intent installed between " +
1460 str( ingressDevice ) + " and " +
1461 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001462 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001463 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001464 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001465 else:
1466 main.log.error( "Error, intent ID not found" )
1467 return None
Jon Hallc6793552016-01-19 14:18:37 -08001468 except AssertionError:
1469 main.log.exception( "" )
1470 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001471 except TypeError:
1472 main.log.exception( self.name + ": Object not as expected" )
1473 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001474 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001475 main.log.error( self.name + ": EOF exception found" )
1476 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001477 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001478 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001479 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001480 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001481
kelvin-onlabd3b64892015-01-20 13:26:24 -08001482 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001483 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001484 ingressDevice,
1485 egressDevice,
1486 portIngress="",
1487 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001488 ethType="",
1489 ethSrc="",
1490 ethDst="",
1491 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001492 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001493 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001494 ipProto="",
1495 ipSrc="",
1496 ipDst="",
1497 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001498 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001499 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001500 setVlan="",
1501 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001502 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001503 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001504 * ingressDevice: device id of ingress device
1505 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001506 Optional:
1507 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001508 * ethSrc: specify ethSrc ( i.e. src mac addr )
1509 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001510 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001511 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001512 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001513 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001514 * ipSrc: specify ip source address
1515 * ipDst: specify ip destination address
1516 * tcpSrc: specify tcp source port
1517 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001518 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001519 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001520 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001521 Description:
kelvin8ec71442015-01-15 16:57:00 -08001522 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001523 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001524 Returns:
1525 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001526
Jon Halle3f39ff2015-01-13 11:50:53 -08001527 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001528 options developers provide for point-to-point
1529 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001530 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001531 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001532 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001533
Jeremy Songsterff553672016-05-12 17:06:23 -07001534 if ethType:
1535 cmd += " --ethType " + str( ethType )
1536 if ethSrc:
1537 cmd += " --ethSrc " + str( ethSrc )
1538 if ethDst:
1539 cmd += " --ethDst " + str( ethDst )
1540 if bandwidth:
1541 cmd += " --bandwidth " + str( bandwidth )
1542 if lambdaAlloc:
1543 cmd += " --lambda "
1544 if ipProto:
1545 cmd += " --ipProto " + str( ipProto )
1546 if ipSrc:
1547 cmd += " --ipSrc " + str( ipSrc )
1548 if ipDst:
1549 cmd += " --ipDst " + str( ipDst )
1550 if tcpSrc:
1551 cmd += " --tcpSrc " + str( tcpSrc )
1552 if tcpDst:
1553 cmd += " --tcpDst " + str( tcpDst )
1554 if vlanId:
1555 cmd += " -v " + str( vlanId )
1556 if setVlan:
1557 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001558 if encap:
1559 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001560 if protected:
1561 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001562
kelvin8ec71442015-01-15 16:57:00 -08001563 # Check whether the user appended the port
1564 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001565 if "/" in ingressDevice:
1566 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001567 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001568 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001569 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001570 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001571 # Would it make sense to throw an exception and exit
1572 # the test?
1573 return None
andrewonlab36af3822014-11-18 17:48:18 -05001574
kelvin8ec71442015-01-15 16:57:00 -08001575 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001576 str( ingressDevice ) + "/" +\
1577 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001578
kelvin-onlabd3b64892015-01-20 13:26:24 -08001579 if "/" in egressDevice:
1580 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001581 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001582 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001583 main.log.error( "You must specify the egress port" )
1584 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001585
kelvin8ec71442015-01-15 16:57:00 -08001586 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001587 str( egressDevice ) + "/" +\
1588 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001589
kelvin-onlab898a6c62015-01-16 14:13:53 -08001590 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001591 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001592 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001593 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001594 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001595 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001596 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001597 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001598 # TODO: print out all the options in this message?
1599 main.log.info( "Point-to-point intent installed between " +
1600 str( ingressDevice ) + " and " +
1601 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001602 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001603 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001604 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001605 else:
1606 main.log.error( "Error, intent ID not found" )
1607 return None
Jon Hallc6793552016-01-19 14:18:37 -08001608 except AssertionError:
1609 main.log.exception( "" )
1610 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001611 except TypeError:
1612 main.log.exception( self.name + ": Object not as expected" )
1613 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001614 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001615 main.log.error( self.name + ": EOF exception found" )
1616 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001617 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001618 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001619 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001620 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001621
kelvin-onlabd3b64892015-01-20 13:26:24 -08001622 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001623 self,
shahshreyac2f97072015-03-19 17:04:29 -07001624 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001625 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001626 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001627 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001628 ethType="",
1629 ethSrc="",
1630 ethDst="",
1631 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001632 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001633 ipProto="",
1634 ipSrc="",
1635 ipDst="",
1636 tcpSrc="",
1637 tcpDst="",
1638 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001639 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001640 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001641 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001642 partial=False,
1643 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001644 """
shahshreyad0c80432014-12-04 16:56:05 -08001645 Note:
shahshreya70622b12015-03-19 17:19:00 -07001646 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001647 is same. That is, all ingress devices include port numbers
1648 with a "/" or all ingress devices could specify device
1649 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001650 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001651 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001652 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001653 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001654 Optional:
1655 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001656 * ethSrc: specify ethSrc ( i.e. src mac addr )
1657 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001658 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001659 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001660 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001661 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001662 * ipSrc: specify ip source address
1663 * ipDst: specify ip destination address
1664 * tcpSrc: specify tcp source port
1665 * tcpDst: specify tcp destination port
1666 * setEthSrc: action to Rewrite Source MAC Address
1667 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001668 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001669 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001670 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001671 Description:
kelvin8ec71442015-01-15 16:57:00 -08001672 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001673 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001674 Returns:
1675 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001676
Jon Halle3f39ff2015-01-13 11:50:53 -08001677 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001678 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001679 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001680 """
shahshreyad0c80432014-12-04 16:56:05 -08001681 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001682 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001683
Jeremy Songsterff553672016-05-12 17:06:23 -07001684 if ethType:
1685 cmd += " --ethType " + str( ethType )
1686 if ethSrc:
1687 cmd += " --ethSrc " + str( ethSrc )
1688 if ethDst:
1689 cmd += " --ethDst " + str( ethDst )
1690 if bandwidth:
1691 cmd += " --bandwidth " + str( bandwidth )
1692 if lambdaAlloc:
1693 cmd += " --lambda "
1694 if ipProto:
1695 cmd += " --ipProto " + str( ipProto )
1696 if ipSrc:
1697 cmd += " --ipSrc " + str( ipSrc )
1698 if ipDst:
1699 cmd += " --ipDst " + str( ipDst )
1700 if tcpSrc:
1701 cmd += " --tcpSrc " + str( tcpSrc )
1702 if tcpDst:
1703 cmd += " --tcpDst " + str( tcpDst )
1704 if setEthSrc:
1705 cmd += " --setEthSrc " + str( setEthSrc )
1706 if setEthDst:
1707 cmd += " --setEthDst " + str( setEthDst )
1708 if vlanId:
1709 cmd += " -v " + str( vlanId )
1710 if setVlan:
1711 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001712 if partial:
1713 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001714 if encap:
1715 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001716
kelvin8ec71442015-01-15 16:57:00 -08001717 # Check whether the user appended the port
1718 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001719
1720 if portIngressList is None:
1721 for ingressDevice in ingressDeviceList:
1722 if "/" in ingressDevice:
1723 cmd += " " + str( ingressDevice )
1724 else:
1725 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001726 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001727 # TODO: perhaps more meaningful return
1728 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001729 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001730 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001731 for ingressDevice, portIngress in zip( ingressDeviceList,
1732 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001733 cmd += " " + \
1734 str( ingressDevice ) + "/" +\
1735 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001736 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001737 main.log.error( "Device list and port list does not " +
1738 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001739 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001740 if "/" in egressDevice:
1741 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001742 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001743 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001744 main.log.error( "You must specify " +
1745 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001746 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001747
kelvin8ec71442015-01-15 16:57:00 -08001748 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001749 str( egressDevice ) + "/" +\
1750 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001751 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001752 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001753 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001754 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001755 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001756 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001757 "intent" )
1758 return None
shahshreyad0c80432014-12-04 16:56:05 -08001759 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001760 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001761 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001762 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001763 else:
1764 main.log.error( "Error, intent ID not found" )
1765 return None
Jon Hallc6793552016-01-19 14:18:37 -08001766 except AssertionError:
1767 main.log.exception( "" )
1768 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001769 except TypeError:
1770 main.log.exception( self.name + ": Object not as expected" )
1771 return None
1772 except pexpect.EOF:
1773 main.log.error( self.name + ": EOF exception found" )
1774 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001775 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001776 except Exception:
1777 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001778 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001779
1780 def addSinglepointToMultipointIntent(
1781 self,
1782 ingressDevice,
1783 egressDeviceList,
1784 portIngress="",
1785 portEgressList=None,
1786 ethType="",
1787 ethSrc="",
1788 ethDst="",
1789 bandwidth="",
1790 lambdaAlloc=False,
1791 ipProto="",
1792 ipSrc="",
1793 ipDst="",
1794 tcpSrc="",
1795 tcpDst="",
1796 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001797 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001798 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001799 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001800 partial=False,
1801 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001802 """
1803 Note:
1804 This function assumes the format of all egress devices
1805 is same. That is, all egress devices include port numbers
1806 with a "/" or all egress devices could specify device
1807 ids and port numbers seperately.
1808 Required:
1809 * EgressDeviceList: List of device ids of egress device
1810 ( Atleast 2 eress devices required in the list )
1811 * ingressDevice: device id of ingress device
1812 Optional:
1813 * ethType: specify ethType
1814 * ethSrc: specify ethSrc ( i.e. src mac addr )
1815 * ethDst: specify ethDst ( i.e. dst mac addr )
1816 * bandwidth: specify bandwidth capacity of link
1817 * lambdaAlloc: if True, intent will allocate lambda
1818 for the specified intent
1819 * ipProto: specify ip protocol
1820 * ipSrc: specify ip source address
1821 * ipDst: specify ip destination address
1822 * tcpSrc: specify tcp source port
1823 * tcpDst: specify tcp destination port
1824 * setEthSrc: action to Rewrite Source MAC Address
1825 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001826 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001827 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001828 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001829 Description:
1830 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1831 specifying device id's and optional fields
1832 Returns:
1833 A string of the intent id or None on error
1834
1835 NOTE: This function may change depending on the
1836 options developers provide for singlepoint-to-multipoint
1837 intent via cli
1838 """
1839 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001840 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001841
Jeremy Songsterff553672016-05-12 17:06:23 -07001842 if ethType:
1843 cmd += " --ethType " + str( ethType )
1844 if ethSrc:
1845 cmd += " --ethSrc " + str( ethSrc )
1846 if ethDst:
1847 cmd += " --ethDst " + str( ethDst )
1848 if bandwidth:
1849 cmd += " --bandwidth " + str( bandwidth )
1850 if lambdaAlloc:
1851 cmd += " --lambda "
1852 if ipProto:
1853 cmd += " --ipProto " + str( ipProto )
1854 if ipSrc:
1855 cmd += " --ipSrc " + str( ipSrc )
1856 if ipDst:
1857 cmd += " --ipDst " + str( ipDst )
1858 if tcpSrc:
1859 cmd += " --tcpSrc " + str( tcpSrc )
1860 if tcpDst:
1861 cmd += " --tcpDst " + str( tcpDst )
1862 if setEthSrc:
1863 cmd += " --setEthSrc " + str( setEthSrc )
1864 if setEthDst:
1865 cmd += " --setEthDst " + str( setEthDst )
1866 if vlanId:
1867 cmd += " -v " + str( vlanId )
1868 if setVlan:
1869 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001870 if partial:
1871 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001872 if encap:
1873 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001874
1875 # Check whether the user appended the port
1876 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001877
kelvin-onlabb9408212015-04-01 13:34:04 -07001878 if "/" in ingressDevice:
1879 cmd += " " + str( ingressDevice )
1880 else:
1881 if not portIngress:
1882 main.log.error( "You must specify " +
1883 "the Ingress port" )
1884 return main.FALSE
1885
1886 cmd += " " +\
1887 str( ingressDevice ) + "/" +\
1888 str( portIngress )
1889
1890 if portEgressList is None:
1891 for egressDevice in egressDeviceList:
1892 if "/" in egressDevice:
1893 cmd += " " + str( egressDevice )
1894 else:
1895 main.log.error( "You must specify " +
1896 "the egress port" )
1897 # TODO: perhaps more meaningful return
1898 return main.FALSE
1899 else:
1900 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001901 for egressDevice, portEgress in zip( egressDeviceList,
1902 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001903 cmd += " " + \
1904 str( egressDevice ) + "/" +\
1905 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001906 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001907 main.log.error( "Device list and port list does not " +
1908 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001909 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001910 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001911 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001912 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001913 # If error, return error message
1914 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001915 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001916 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001917 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001918 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001919 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001920 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001921 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001922 else:
1923 main.log.error( "Error, intent ID not found" )
1924 return None
Jon Hallc6793552016-01-19 14:18:37 -08001925 except AssertionError:
1926 main.log.exception( "" )
1927 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001928 except TypeError:
1929 main.log.exception( self.name + ": Object not as expected" )
1930 return None
shahshreyad0c80432014-12-04 16:56:05 -08001931 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001932 main.log.error( self.name + ": EOF exception found" )
1933 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001934 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001935 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001936 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001937 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001938
Hari Krishna9e232602015-04-13 17:29:08 -07001939 def addMplsIntent(
1940 self,
1941 ingressDevice,
1942 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001943 ingressPort="",
1944 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001945 ethType="",
1946 ethSrc="",
1947 ethDst="",
1948 bandwidth="",
1949 lambdaAlloc=False,
1950 ipProto="",
1951 ipSrc="",
1952 ipDst="",
1953 tcpSrc="",
1954 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001955 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001956 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001957 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001958 """
1959 Required:
1960 * ingressDevice: device id of ingress device
1961 * egressDevice: device id of egress device
1962 Optional:
1963 * ethType: specify ethType
1964 * ethSrc: specify ethSrc ( i.e. src mac addr )
1965 * ethDst: specify ethDst ( i.e. dst mac addr )
1966 * bandwidth: specify bandwidth capacity of link
1967 * lambdaAlloc: if True, intent will allocate lambda
1968 for the specified intent
1969 * ipProto: specify ip protocol
1970 * ipSrc: specify ip source address
1971 * ipDst: specify ip destination address
1972 * tcpSrc: specify tcp source port
1973 * tcpDst: specify tcp destination port
1974 * ingressLabel: Ingress MPLS label
1975 * egressLabel: Egress MPLS label
1976 Description:
1977 Adds MPLS intent by
1978 specifying device id's and optional fields
1979 Returns:
1980 A string of the intent id or None on error
1981
1982 NOTE: This function may change depending on the
1983 options developers provide for MPLS
1984 intent via cli
1985 """
1986 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001987 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001988
Jeremy Songsterff553672016-05-12 17:06:23 -07001989 if ethType:
1990 cmd += " --ethType " + str( ethType )
1991 if ethSrc:
1992 cmd += " --ethSrc " + str( ethSrc )
1993 if ethDst:
1994 cmd += " --ethDst " + str( ethDst )
1995 if bandwidth:
1996 cmd += " --bandwidth " + str( bandwidth )
1997 if lambdaAlloc:
1998 cmd += " --lambda "
1999 if ipProto:
2000 cmd += " --ipProto " + str( ipProto )
2001 if ipSrc:
2002 cmd += " --ipSrc " + str( ipSrc )
2003 if ipDst:
2004 cmd += " --ipDst " + str( ipDst )
2005 if tcpSrc:
2006 cmd += " --tcpSrc " + str( tcpSrc )
2007 if tcpDst:
2008 cmd += " --tcpDst " + str( tcpDst )
2009 if ingressLabel:
2010 cmd += " --ingressLabel " + str( ingressLabel )
2011 if egressLabel:
2012 cmd += " --egressLabel " + str( egressLabel )
2013 if priority:
2014 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07002015
2016 # Check whether the user appended the port
2017 # or provided it as an input
2018 if "/" in ingressDevice:
2019 cmd += " " + str( ingressDevice )
2020 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002021 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002022 main.log.error( "You must specify the ingress port" )
2023 return None
2024
2025 cmd += " " + \
2026 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002027 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07002028
2029 if "/" in egressDevice:
2030 cmd += " " + str( egressDevice )
2031 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002032 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002033 main.log.error( "You must specify the egress port" )
2034 return None
2035
2036 cmd += " " +\
2037 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002038 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07002039
2040 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08002041 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002042 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07002043 # If error, return error message
2044 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002045 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07002046 return None
2047 else:
2048 # TODO: print out all the options in this message?
2049 main.log.info( "MPLS intent installed between " +
2050 str( ingressDevice ) + " and " +
2051 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002052 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07002053 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002054 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07002055 else:
2056 main.log.error( "Error, intent ID not found" )
2057 return None
Jon Hallc6793552016-01-19 14:18:37 -08002058 except AssertionError:
2059 main.log.exception( "" )
2060 return None
Hari Krishna9e232602015-04-13 17:29:08 -07002061 except TypeError:
2062 main.log.exception( self.name + ": Object not as expected" )
2063 return None
2064 except pexpect.EOF:
2065 main.log.error( self.name + ": EOF exception found" )
2066 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002067 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002068 except Exception:
2069 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002070 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002071
Jon Hallefbd9792015-03-05 16:11:36 -08002072 def removeIntent( self, intentId, app='org.onosproject.cli',
2073 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002074 """
shahshreya1c818fc2015-02-26 13:44:08 -08002075 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07002076 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08002077 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07002078 -p or --purge: Purge the intent from the store after removal
2079
Jon Halle3f39ff2015-01-13 11:50:53 -08002080 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002081 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002082 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002083 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002084 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002085 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002086 if purge:
2087 cmdStr += " -p"
2088 if sync:
2089 cmdStr += " -s"
2090
2091 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002092 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002093 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002094 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002095 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002096 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002097 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002098 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002099 # TODO: Should this be main.TRUE
2100 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002101 except AssertionError:
2102 main.log.exception( "" )
2103 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002104 except TypeError:
2105 main.log.exception( self.name + ": Object not as expected" )
2106 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002107 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002108 main.log.error( self.name + ": EOF exception found" )
2109 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002110 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002111 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002112 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002113 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002114
YPZhangfebf7302016-05-24 16:45:56 -07002115 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002116 """
2117 Description:
2118 Remove all the intents
2119 Optional args:-
2120 -s or --sync: Waits for the removal before returning
2121 -p or --purge: Purge the intent from the store after removal
2122 Returns:
2123 Returns main.TRUE if all intents are removed, otherwise returns
2124 main.FALSE; Returns None for exception
2125 """
2126 try:
2127 cmdStr = "remove-intent"
2128 if purge:
2129 cmdStr += " -p"
2130 if sync:
2131 cmdStr += " -s"
2132
2133 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002134 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002135 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002136 assert "Command not found:" not in handle, handle
2137 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002138 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002139 return main.FALSE
2140 else:
2141 return main.TRUE
2142 except AssertionError:
2143 main.log.exception( "" )
2144 return None
2145 except TypeError:
2146 main.log.exception( self.name + ": Object not as expected" )
2147 return None
2148 except pexpect.EOF:
2149 main.log.error( self.name + ": EOF exception found" )
2150 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002151 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002152 except Exception:
2153 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002154 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002155
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002156 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002157 """
2158 Purges all WITHDRAWN Intents
2159 """
2160 try:
2161 cmdStr = "purge-intents"
2162 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002163 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002164 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002165 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002166 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002167 return main.FALSE
2168 else:
2169 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002170 except AssertionError:
2171 main.log.exception( "" )
2172 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002173 except TypeError:
2174 main.log.exception( self.name + ": Object not as expected" )
2175 return None
2176 except pexpect.EOF:
2177 main.log.error( self.name + ": EOF exception found" )
2178 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002179 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002180 except Exception:
2181 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002182 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002183
Devin Lime6fe3c42017-10-18 16:28:40 -07002184 def wipeout( self ):
2185 """
2186 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2187 """
2188 try:
2189 cmdStr = "wipe-out please"
2190 handle = self.sendline( cmdStr, timeout=60 )
2191 assert handle is not None, "Error in sendline"
2192 assert "Command not found:" not in handle, handle
2193 return main.TRUE
2194 except AssertionError:
2195 main.log.exception( "" )
2196 return None
2197 except TypeError:
2198 main.log.exception( self.name + ": Object not as expected" )
2199 return None
2200 except pexpect.EOF:
2201 main.log.error( self.name + ": EOF exception found" )
2202 main.log.error( self.name + ": " + self.handle.before )
2203 main.cleanAndExit()
2204 except Exception:
2205 main.log.exception( self.name + ": Uncaught exception!" )
2206 main.cleanAndExit()
2207
kelvin-onlabd3b64892015-01-20 13:26:24 -08002208 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002209 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002210 NOTE: This method should be used after installing application:
2211 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002212 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002213 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002214 Description:
2215 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002216 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002217 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002218 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002219 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002220 cmdStr += " -j"
2221 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002222 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002223 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002224 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002225 except AssertionError:
2226 main.log.exception( "" )
2227 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002228 except TypeError:
2229 main.log.exception( self.name + ": Object not as expected" )
2230 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002231 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002232 main.log.error( self.name + ": EOF exception found" )
2233 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002234 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002235 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002236 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002237 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002238
pingping-lin54b03372015-08-13 14:43:10 -07002239 def ipv4RouteNumber( self ):
2240 """
2241 NOTE: This method should be used after installing application:
2242 onos-app-sdnip
2243 Description:
2244 Obtain the total IPv4 routes number in the system
2245 """
2246 try:
Pratik Parab57963572017-05-09 11:37:54 -07002247 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002248 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002249 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002250 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002251 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002252 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002253 except AssertionError:
2254 main.log.exception( "" )
2255 return None
2256 except ( TypeError, ValueError ):
2257 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002258 return None
2259 except pexpect.EOF:
2260 main.log.error( self.name + ": EOF exception found" )
2261 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002262 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002263 except Exception:
2264 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002265 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002266
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002267 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002268 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002269 """
2270 Description:
2271 Obtain Bandwidth Allocation Information from ONOS cli.
2272 """
2273 try:
2274 cmdStr = "allocations"
2275 if jsonFormat:
2276 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002277 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002278 assert handle is not None, "Error in sendline"
2279 assert "Command not found:" not in handle, handle
2280 return handle
2281 except AssertionError:
2282 main.log.exception( "" )
2283 return None
2284 except ( TypeError, ValueError ):
2285 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2286 return None
2287 except pexpect.EOF:
2288 main.log.error( self.name + ": EOF exception found" )
2289 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002290 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002291 except Exception:
2292 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002293 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002294
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002295 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002296 """
andrewonlabe6745342014-10-17 14:29:13 -04002297 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002298 Obtain intents from the ONOS cli.
2299 Optional:
2300 * jsonFormat: Enable output formatting in json, default to True
2301 * summary: Whether only output the intent summary, defaults to False
2302 * type: Only output a certain type of intent. This options is valid
2303 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002304 """
andrewonlabe6745342014-10-17 14:29:13 -04002305 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002306 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002307 if summary:
2308 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002309 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002310 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002311 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002312 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002313 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002314 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002315 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002316 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002317 else:
Jon Hallff566d52016-01-15 14:45:36 -08002318 intentType = ""
2319 # IF we want the summary of a specific intent type
2320 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002321 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002322 if intentType in jsonResult.keys():
2323 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002324 else:
Jon Hallff566d52016-01-15 14:45:36 -08002325 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002326 return handle
2327 else:
2328 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002329 except AssertionError:
2330 main.log.exception( "" )
2331 return None
2332 except ( TypeError, ValueError ):
2333 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002334 return None
2335 except pexpect.EOF:
2336 main.log.error( self.name + ": EOF exception found" )
2337 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002338 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002339 except Exception:
2340 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002341 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002342
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002343 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002344 """
You Wangfdcbfc42016-05-16 12:16:53 -07002345 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002346 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002347 list of intent IDs.
2348 Parameters:
2349 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002350 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002351 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002352 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002353 accepted.
2354 Returns a list of dictionaries if a list of intent IDs is accepted,
2355 and each dictionary maps 'id' to the Intent ID and 'state' to
2356 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002357 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002358
kelvin-onlab54400a92015-02-26 18:05:51 -08002359 try:
2360 state = "State is Undefined"
2361 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002362 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002363 else:
Jon Hallc6793552016-01-19 14:18:37 -08002364 rawJson = intentsJson
2365 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002366 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002367 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002368 if intentsId == intent[ 'id' ]:
2369 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002370 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002371 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002372 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002373 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002374 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002375 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002376 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002377 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002378 for intent in parsedIntentsJson:
2379 if intentsId[ i ] == intent[ 'id' ]:
2380 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002381 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002382 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002383 break
Jon Hallefbd9792015-03-05 16:11:36 -08002384 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002385 main.log.warn( "Could not find all intents in ONOS output" )
2386 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002387 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002388 else:
Jon Hall53158082017-05-18 11:17:00 -07002389 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002390 return None
Jon Hallc6793552016-01-19 14:18:37 -08002391 except ( TypeError, ValueError ):
2392 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002393 return None
2394 except pexpect.EOF:
2395 main.log.error( self.name + ": EOF exception found" )
2396 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002397 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002398 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002399 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002400 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002401
Jon Hallf539eb92017-05-22 17:18:42 -07002402 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002403 """
2404 Description:
2405 Check intents state
2406 Required:
2407 intentsId - List of intents ID to be checked
2408 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002409 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002410 state in the list.
2411 *NOTE: You can pass in a list of expected state,
2412 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002413 Return:
Jon Hall53158082017-05-18 11:17:00 -07002414 Returns main.TRUE only if all intent are the same as expected states,
2415 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002416 """
2417 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002418 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002419 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002420
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002421 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002422 intentsDict = []
2423 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002424 if isinstance( intentsId, types.StringType ) \
2425 and intent.get( 'id' ) == intentsId:
2426 intentsDict.append( intent )
2427 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002428 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002429 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002430
2431 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002432 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002433 "getting intents state" )
2434 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002435
2436 if isinstance( expectedState, types.StringType ):
2437 for intents in intentsDict:
2438 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002439 main.log.debug( self.name + " : Intent ID - " +
2440 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002441 " actual state = " +
2442 intents.get( 'state' )
2443 + " does not equal expected state = "
2444 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002445 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002446 elif isinstance( expectedState, types.ListType ):
2447 for intents in intentsDict:
2448 if not any( state == intents.get( 'state' ) for state in
2449 expectedState ):
2450 main.log.debug( self.name + " : Intent ID - " +
2451 intents.get( 'id' ) +
2452 " actual state = " +
2453 intents.get( 'state' ) +
2454 " does not equal expected states = "
2455 + str( expectedState ) )
2456 returnValue = main.FALSE
2457
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002458 if returnValue == main.TRUE:
2459 main.log.info( self.name + ": All " +
2460 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002461 " intents are in " + str( expectedState ) +
2462 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002463 return returnValue
2464 except TypeError:
2465 main.log.exception( self.name + ": Object not as expected" )
2466 return None
2467 except pexpect.EOF:
2468 main.log.error( self.name + ": EOF exception found" )
2469 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002470 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002471 except Exception:
2472 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002473 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002474
Jon Hallf539eb92017-05-22 17:18:42 -07002475 def compareBandwidthAllocations( self, expectedAllocations ):
2476 """
2477 Description:
2478 Compare the allocated bandwidth with the given allocations
2479 Required:
2480 expectedAllocations - The expected ONOS output of the allocations command
2481 Return:
2482 Returns main.TRUE only if all intent are the same as expected states,
2483 otherwise returns main.FALSE.
2484 """
2485 # FIXME: Convert these string comparisons to object comparisons
2486 try:
2487 returnValue = main.TRUE
2488 bandwidthFailed = False
2489 rawAlloc = self.allocations()
2490 expectedFormat = StringIO( expectedAllocations )
2491 ONOSOutput = StringIO( rawAlloc )
2492 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2493 str( expectedFormat ) ) )
2494
2495 for actual, expected in izip( ONOSOutput, expectedFormat ):
2496 actual = actual.rstrip()
2497 expected = expected.rstrip()
2498 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2499 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002500 marker1 = actual.find( 'allocated' )
2501 m1 = actual[ :marker1 ]
2502 marker2 = expected.find( 'allocated' )
2503 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002504 if m1 != m2:
2505 bandwidthFailed = True
2506 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2507 bandwidthFailed = True
2508 expectedFormat.close()
2509 ONOSOutput.close()
2510
2511 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002512 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002513 returnValue = main.FALSE
2514 return returnValue
2515 except TypeError:
2516 main.log.exception( self.name + ": Object not as expected" )
2517 return None
2518 except pexpect.EOF:
2519 main.log.error( self.name + ": EOF exception found" )
2520 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002521 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002522 except Exception:
2523 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002524 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002525
You Wang66518af2016-05-16 15:32:59 -07002526 def compareIntent( self, intentDict ):
2527 """
2528 Description:
2529 Compare the intent ids and states provided in the argument with all intents in ONOS
2530 Return:
2531 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2532 Arguments:
2533 intentDict: a dictionary which maps intent ids to intent states
2534 """
2535 try:
2536 intentsRaw = self.intents()
2537 intentsJson = json.loads( intentsRaw )
2538 intentDictONOS = {}
2539 for intent in intentsJson:
2540 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002541 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002542 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002543 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002544 str( len( intentDict ) ) + " expected and " +
2545 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002546 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002547 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002548 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002549 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2550 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002551 else:
2552 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2553 main.log.debug( self.name + ": intent ID - " + intentID +
2554 " expected state is " + intentDict[ intentID ] +
2555 " but actual state is " + intentDictONOS[ intentID ] )
2556 returnValue = main.FALSE
2557 intentDictONOS.pop( intentID )
2558 if len( intentDictONOS ) > 0:
2559 returnValue = main.FALSE
2560 for intentID in intentDictONOS.keys():
2561 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002562 if returnValue == main.TRUE:
2563 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2564 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002565 except KeyError:
2566 main.log.exception( self.name + ": KeyError exception found" )
2567 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002568 except ( TypeError, ValueError ):
2569 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002570 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002571 except pexpect.EOF:
2572 main.log.error( self.name + ": EOF exception found" )
2573 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002574 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002575 except Exception:
2576 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002577 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002578
YPZhang14a4aa92016-07-15 13:37:15 -07002579 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002580 """
2581 Description:
2582 Check the number of installed intents.
2583 Optional:
2584 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002585 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002586 Return:
2587 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2588 , otherwise, returns main.FALSE.
2589 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002590
GlennRCed771242016-01-13 17:02:47 -08002591 try:
2592 cmd = "intents -s -j"
2593
2594 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002595 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002596 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002597 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002598 response = json.loads( response )
2599
2600 # get total and installed number, see if they are match
2601 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002602 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002603 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2604 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002605 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002606 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2607 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002608 return main.FALSE
2609
Jon Hallc6793552016-01-19 14:18:37 -08002610 except ( TypeError, ValueError ):
2611 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002612 return None
2613 except pexpect.EOF:
2614 main.log.error( self.name + ": EOF exception found" )
2615 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002616 if noExit:
2617 return main.FALSE
2618 else:
Devin Lim44075962017-08-11 10:56:37 -07002619 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002620 except pexpect.TIMEOUT:
2621 main.log.error( self.name + ": ONOS timeout" )
2622 return None
GlennRCed771242016-01-13 17:02:47 -08002623 except Exception:
2624 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002625 if noExit:
2626 return main.FALSE
2627 else:
Devin Lim44075962017-08-11 10:56:37 -07002628 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002629
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002630 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002631 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002632 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002633 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002634 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002635 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002636 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002637 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002638 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002639 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002640 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002641 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002642 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002643 cmdStr += " -n"
2644 cmdStr += " " + state
2645 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002646 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002647 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002648 assert "Command not found:" not in handle, handle
2649 if re.search( "Error:", handle ):
2650 main.log.error( self.name + ": flows() response: " +
2651 str( handle ) )
2652 return handle
2653 except AssertionError:
2654 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002655 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002656 except TypeError:
2657 main.log.exception( self.name + ": Object not as expected" )
2658 return None
Jon Hallc6793552016-01-19 14:18:37 -08002659 except pexpect.TIMEOUT:
2660 main.log.error( self.name + ": ONOS timeout" )
2661 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002662 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002663 main.log.error( self.name + ": EOF exception found" )
2664 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002665 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002666 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002667 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002668 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002669
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002670 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002671 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002672 count = int( count ) if count else 0
2673 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002674
Jon Halle0f0b342017-04-18 11:43:47 -07002675 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002676 """
2677 Description:
GlennRCed771242016-01-13 17:02:47 -08002678 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002679 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2680 if the count of those states is 0, which means all current flows
2681 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002682 Optional:
GlennRCed771242016-01-13 17:02:47 -08002683 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002684 Return:
2685 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002686 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002687 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002688 """
2689 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002690 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002691 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002692 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002693 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002694 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002695 if rawFlows:
2696 # if we didn't get flows or flows function return None, we should return
2697 # main.Flase
2698 checkedStates.append( json.loads( rawFlows ) )
2699 else:
2700 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002701 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002702 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002703 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002704 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002705 except TypeError:
2706 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002707 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002708
GlennRCed771242016-01-13 17:02:47 -08002709 # We want to count PENDING_ADD if isPENDING is true
2710 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002711 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002712 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002713 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002714 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002715 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002716 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002717 except ( TypeError, ValueError ):
2718 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002719 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002720
YPZhang240842b2016-05-17 12:00:50 -07002721 except AssertionError:
2722 main.log.exception( "" )
2723 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002724 except pexpect.TIMEOUT:
2725 main.log.error( self.name + ": ONOS timeout" )
2726 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002727 except pexpect.EOF:
2728 main.log.error( self.name + ": EOF exception found" )
2729 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002730 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002731 except Exception:
2732 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002733 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002734
GlennRCed771242016-01-13 17:02:47 -08002735 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002736 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002737 """
andrewonlab87852b02014-11-19 18:44:19 -05002738 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002739 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002740 a specific point-to-point intent definition
2741 Required:
GlennRCed771242016-01-13 17:02:47 -08002742 * ingress: specify source dpid
2743 * egress: specify destination dpid
2744 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002745 Optional:
GlennRCed771242016-01-13 17:02:47 -08002746 * offset: the keyOffset is where the next batch of intents
2747 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002748 * noExit: If set to True, TestON will not exit if any error when issus command
2749 * getResponse: If set to True, function will return ONOS response.
2750
GlennRCed771242016-01-13 17:02:47 -08002751 Returns: If failed to push test intents, it will returen None,
2752 if successful, return true.
2753 Timeout expection will return None,
2754 TypeError will return false
2755 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002756 """
andrewonlab87852b02014-11-19 18:44:19 -05002757 try:
GlennRCed771242016-01-13 17:02:47 -08002758 if background:
2759 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002760 else:
GlennRCed771242016-01-13 17:02:47 -08002761 back = ""
2762 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002763 ingress,
2764 egress,
2765 batchSize,
2766 offset,
2767 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002768 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002769 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002770 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002771 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002772 if getResponse:
2773 return response
2774
GlennRCed771242016-01-13 17:02:47 -08002775 # TODO: We should handle if there is failure in installation
2776 return main.TRUE
2777
Jon Hallc6793552016-01-19 14:18:37 -08002778 except AssertionError:
2779 main.log.exception( "" )
2780 return None
GlennRCed771242016-01-13 17:02:47 -08002781 except pexpect.TIMEOUT:
2782 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002783 return None
andrewonlab87852b02014-11-19 18:44:19 -05002784 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002785 main.log.error( self.name + ": EOF exception found" )
2786 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002787 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002788 except TypeError:
2789 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002790 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002791 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002792 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002793 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002794
YPZhangebf9eb52016-05-12 15:20:24 -07002795 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002796 """
2797 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002798 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002799 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002800 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002801 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002802 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002803
YPZhangb5d3f832016-01-23 22:54:26 -08002804 try:
YPZhange3109a72016-02-02 11:25:37 -08002805 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002806 cmd = "flows -c added"
2807 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2808 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002809 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002810 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002811 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002812 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002813 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002814 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002815 return None
2816 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002817
You Wangd3097f72018-12-12 11:56:03 -08002818 except IndexError:
2819 main.log.exception( "{}: Object not as expected!".format( self.name ) )
2820 main.log.debug( "rawFlows: {}".format( rawFlows ) )
2821 return None
You Wangd3cb2ce2016-05-16 14:01:24 -07002822 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002823 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002824 return None
2825 except pexpect.EOF:
2826 main.log.error( self.name + ": EOF exception found" )
2827 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002828 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002829 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002830 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002831 except pexpect.TIMEOUT:
2832 main.log.error( self.name + ": ONOS timeout" )
2833 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002834 except Exception:
2835 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002836 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002837 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002838 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002839
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002840 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002841 """
2842 Description:
2843 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002844 Optional:
2845 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002846 Return:
2847 The number of intents
2848 """
2849 try:
2850 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002851 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002852 if response is None:
2853 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002854 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002855 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002856 except ( TypeError, ValueError ):
2857 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002858 return None
2859 except pexpect.EOF:
2860 main.log.error( self.name + ": EOF exception found" )
2861 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002862 if noExit:
2863 return -1
2864 else:
Devin Lim44075962017-08-11 10:56:37 -07002865 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002866 except Exception:
2867 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002868 if noExit:
2869 return -1
2870 else:
Devin Lim44075962017-08-11 10:56:37 -07002871 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002872
kelvin-onlabd3b64892015-01-20 13:26:24 -08002873 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002874 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002875 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002876 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002877 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002878 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002879 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002880 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002881 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002882 cmdStr += " -j"
2883 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002884 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002885 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002886 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002887 except AssertionError:
2888 main.log.exception( "" )
2889 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002890 except TypeError:
2891 main.log.exception( self.name + ": Object not as expected" )
2892 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002893 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002894 main.log.error( self.name + ": EOF exception found" )
2895 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002896 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002897 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002898 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002899 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002900
kelvin-onlabd3b64892015-01-20 13:26:24 -08002901 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002902 """
2903 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002904 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002905 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002906 """
andrewonlab867212a2014-10-22 20:13:38 -04002907 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002908 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002909 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002910 cmdStr += " -j"
2911 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002912 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002913 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002914 if handle:
2915 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002916 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002917 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002918 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002919 else:
2920 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002921 except AssertionError:
2922 main.log.exception( "" )
2923 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002924 except TypeError:
2925 main.log.exception( self.name + ": Object not as expected" )
2926 return None
andrewonlab867212a2014-10-22 20:13:38 -04002927 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002928 main.log.error( self.name + ": EOF exception found" )
2929 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002930 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002931 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002932 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002933 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002934
kelvin8ec71442015-01-15 16:57:00 -08002935 # Wrapper functions ****************
2936 # Wrapper functions use existing driver
2937 # functions and extends their use case.
2938 # For example, we may use the output of
2939 # a normal driver function, and parse it
2940 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002941
kelvin-onlabd3b64892015-01-20 13:26:24 -08002942 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002943 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002944 Description:
2945 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002946 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002947 try:
kelvin8ec71442015-01-15 16:57:00 -08002948 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002949 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002950 if intentsStr is None:
2951 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002952 # Convert to a dictionary
2953 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002954 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002955 for intent in intents:
2956 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002957 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002958 except TypeError:
2959 main.log.exception( self.name + ": Object not as expected" )
2960 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002961 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002962 main.log.error( self.name + ": EOF exception found" )
2963 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002964 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002965 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002966 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002967 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002968
You Wang3c276252016-09-21 15:21:36 -07002969 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002970 """
2971 Determine the number of flow rules for the given device id that are
2972 in the added state
You Wang3c276252016-09-21 15:21:36 -07002973 Params:
2974 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002975 """
2976 try:
You Wang3c276252016-09-21 15:21:36 -07002977 if core:
2978 cmdStr = "flows any " + str( deviceId ) + " | " +\
2979 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2980 else:
2981 cmdStr = "flows any " + str( deviceId ) + " | " +\
2982 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08002983 handle = self.lineCount( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002984 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002985 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002986 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002987 except AssertionError:
2988 main.log.exception( "" )
2989 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002990 except pexpect.EOF:
2991 main.log.error( self.name + ": EOF exception found" )
2992 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002993 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002994 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002995 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002996 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002997
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002998 def groupAddedCount( self, deviceId, core=False ):
2999 """
3000 Determine the number of group rules for the given device id that are
3001 in the added state
3002 Params:
3003 core: if True, only return the number of core groups added
3004 """
3005 try:
3006 if core:
3007 cmdStr = "groups any " + str( deviceId ) + " | " +\
3008 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
3009 else:
3010 cmdStr = "groups any " + str( deviceId ) + " | " +\
3011 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003012 handle = self.lineCount( cmdStr )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003013 assert handle is not None, "Error in sendline"
3014 assert "Command not found:" not in handle, handle
3015 return handle
3016 except AssertionError:
3017 main.log.exception( "" )
3018 return None
3019 except pexpect.EOF:
3020 main.log.error( self.name + ": EOF exception found" )
3021 main.log.error( self.name + ": " + self.handle.before )
3022 main.cleanAndExit()
3023 except Exception:
3024 main.log.exception( self.name + ": Uncaught exception!" )
3025 main.cleanAndExit()
3026
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003027 def addStaticRoute( self, subnet, intf):
3028 """
3029 Adds a static route to onos.
3030 Params:
3031 subnet: The subnet reaching through this route
3032 intf: The interface this route is reachable through
3033 """
3034 try:
3035 cmdStr = "route-add " + subnet + " " + intf
3036 handle = self.sendline( cmdStr )
3037 assert handle is not None, "Error in sendline"
3038 assert "Command not found:" not in handle, handle
3039 return handle
3040 except AssertionError:
3041 main.log.exception( "" )
3042 return None
3043 except pexpect.EOF:
3044 main.log.error( self.name + ": EOF exception found" )
3045 main.log.error( self.name + ": " + self.handle.before )
3046 main.cleanAndExit()
3047 except Exception:
3048 main.log.exception( self.name + ": Uncaught exception!" )
3049 main.cleanAndExit()
3050
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003051 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
3052 """
3053 Description:
3054 Check whether the number of groups for the given device id that
3055 are in ADDED state is bigger than minGroupCount.
3056 Required:
3057 * deviceId: device id to check the number of added group rules
3058 Optional:
3059 * minGroupCount: the number of groups to compare
3060 * core: if True, only check the number of core groups added
3061 * comparison: if 0, compare with greater than minFlowCount
3062 * if 1, compare with equal to minFlowCount
3063 Return:
3064 Returns the number of groups if it is bigger than minGroupCount,
3065 returns main.FALSE otherwise.
3066 """
3067 count = self.groupAddedCount( deviceId, core )
3068 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003069 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003070 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
3071
You Wangc02f3be2018-05-18 12:14:23 -07003072 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003073 """
3074 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07003075 deviceId: Id of the device from which we retrieve groups
3076 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003077 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003078 try:
You Wangc02f3be2018-05-18 12:14:23 -07003079 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
3080 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003081 assert handle is not None, "Error in sendline"
3082 assert "Command not found:" not in handle, handle
3083 return handle
3084 except AssertionError:
3085 main.log.exception( "" )
3086 return None
3087 except TypeError:
3088 main.log.exception( self.name + ": Object not as expected" )
3089 return None
3090 except pexpect.EOF:
3091 main.log.error( self.name + ": EOF exception found" )
3092 main.log.error( self.name + ": " + self.handle.before )
3093 main.cleanAndExit()
3094 except Exception:
3095 main.log.exception( self.name + ": Uncaught exception!" )
3096 main.cleanAndExit()
3097
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003098 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003099 """
3100 Description:
3101 Check whether the number of flow rules for the given device id that
3102 are in ADDED state is bigger than minFlowCount.
3103 Required:
3104 * deviceId: device id to check the number of added flow rules
3105 Optional:
3106 * minFlowCount: the number of flow rules to compare
3107 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003108 * comparison: if 0, compare with greater than minFlowCount
3109 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003110 Return:
3111 Returns the number of flow rules if it is bigger than minFlowCount,
3112 returns main.FALSE otherwise.
3113 """
3114 count = self.flowAddedCount( deviceId, core )
3115 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003116 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003117 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003118
kelvin-onlabd3b64892015-01-20 13:26:24 -08003119 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003120 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003121 Use 'devices' function to obtain list of all devices
3122 and parse the result to obtain a list of all device
3123 id's. Returns this list. Returns empty list if no
3124 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003125 List is ordered sequentially
3126
andrewonlab3e15ead2014-10-15 14:21:34 -04003127 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003128 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003129 the ids. By obtaining the list of device ids on the fly,
3130 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003131 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003132 try:
kelvin8ec71442015-01-15 16:57:00 -08003133 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003134 devicesStr = self.devices( jsonFormat=False )
3135 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003136
kelvin-onlabd3b64892015-01-20 13:26:24 -08003137 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003138 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003139 return idList
kelvin8ec71442015-01-15 16:57:00 -08003140
3141 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003142 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003143 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003144 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003145 # Split list further into arguments before and after string
3146 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003147 # append to idList
3148 for arg in tempList:
3149 idList.append( arg.split( "id=" )[ 1 ] )
3150 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003151
Jon Halld4d4b372015-01-28 16:02:41 -08003152 except TypeError:
3153 main.log.exception( self.name + ": Object not as expected" )
3154 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003155 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003156 main.log.error( self.name + ": EOF exception found" )
3157 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003158 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003159 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003160 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003161 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003162
kelvin-onlabd3b64892015-01-20 13:26:24 -08003163 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003164 """
andrewonlab7c211572014-10-15 16:45:20 -04003165 Uses 'nodes' function to obtain list of all nodes
3166 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003167 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003168 Returns:
3169 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003170 """
andrewonlab7c211572014-10-15 16:45:20 -04003171 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003172 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003173 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003174 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003175 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003176 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003177 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003178 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003179 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003180 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003181 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003182 except ( TypeError, ValueError ):
3183 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003184 return None
andrewonlab7c211572014-10-15 16:45:20 -04003185 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003186 main.log.error( self.name + ": EOF exception found" )
3187 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003188 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003189 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003190 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003191 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003192
kelvin-onlabd3b64892015-01-20 13:26:24 -08003193 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003194 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003195 Return the first device from the devices api whose 'id' contains 'dpid'
3196 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003197 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003198 try:
kelvin8ec71442015-01-15 16:57:00 -08003199 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003200 return None
3201 else:
kelvin8ec71442015-01-15 16:57:00 -08003202 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003203 rawDevices = self.devices()
3204 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003205 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003206 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003207 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3208 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003209 return device
3210 return None
Jon Hallc6793552016-01-19 14:18:37 -08003211 except ( TypeError, ValueError ):
3212 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003213 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003214 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003215 main.log.error( self.name + ": EOF exception found" )
3216 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003217 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003218 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003219 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003220 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003221
You Wang24139872016-05-03 11:48:47 -07003222 def getTopology( self, topologyOutput ):
3223 """
3224 Definition:
3225 Loads a json topology output
3226 Return:
3227 topology = current ONOS topology
3228 """
3229 import json
3230 try:
3231 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003232 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003233 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003234 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003235 except ( TypeError, ValueError ):
3236 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3237 return None
You Wang24139872016-05-03 11:48:47 -07003238 except pexpect.EOF:
3239 main.log.error( self.name + ": EOF exception found" )
3240 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003241 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003242 except Exception:
3243 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003244 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003245
Pier6a0c4de2018-03-18 16:01:30 -07003246 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003247 """
Jon Hallefbd9792015-03-05 16:11:36 -08003248 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003249 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003250 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003251
Flavio Castro82ee2f62016-06-07 15:04:12 -07003252 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003253 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003254 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003255 logLevel = level to log to.
3256 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003257
Jon Hallefbd9792015-03-05 16:11:36 -08003258 Returns: main.TRUE if the number of switches and links are correct,
3259 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003260 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003261 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003262 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003263 try:
You Wang13310252016-07-31 10:56:14 -07003264 summary = self.summary()
3265 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003266 except ( TypeError, ValueError ):
3267 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3268 return main.ERROR
3269 try:
3270 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003271 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003272 return main.ERROR
3273 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003274 # Is the number of switches is what we expected
3275 devices = topology.get( 'devices', False )
3276 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003277 nodes = summary.get( 'nodes', False )
3278 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003279 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003280 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003281 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003282 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003283 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3284 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003285 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003286 output = output + "The number of links and switches match "\
3287 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003288 result = main.TRUE
3289 else:
You Wang24139872016-05-03 11:48:47 -07003290 output = output + \
3291 "The number of links and switches does not match " + \
3292 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003293 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003294 output = output + "\n ONOS sees %i devices" % int( devices )
3295 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003296 if int( numolink ) > 0:
3297 output = output + "and %i links " % int( links )
3298 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003299 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003300 output = output + "and %i controllers " % int( nodes )
3301 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003302 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003303 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003304 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003305 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003306 else:
You Wang24139872016-05-03 11:48:47 -07003307 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003308 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003309 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003310 main.log.error( self.name + ": EOF exception found" )
3311 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003312 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003313 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003314 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003315 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003316
kelvin-onlabd3b64892015-01-20 13:26:24 -08003317 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003318 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003319 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003320 deviceId must be the id of a device as seen in the onos devices command
3321 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003322 role must be either master, standby, or none
3323
Jon Halle3f39ff2015-01-13 11:50:53 -08003324 Returns:
3325 main.TRUE or main.FALSE based on argument verification and
3326 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003327 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003328 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003329 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003330 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003331 cmdStr = "device-role " +\
3332 str( deviceId ) + " " +\
3333 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003334 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003335 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003336 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003337 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003338 if re.search( "Error", handle ):
3339 # end color output to escape any colours
3340 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003341 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003342 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003343 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003344 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003345 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003346 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003347 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003348 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003349 except AssertionError:
3350 main.log.exception( "" )
3351 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003352 except TypeError:
3353 main.log.exception( self.name + ": Object not as expected" )
3354 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003355 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003356 main.log.error( self.name + ": EOF exception found" )
3357 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003358 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003359 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003360 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003361 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003362
kelvin-onlabd3b64892015-01-20 13:26:24 -08003363 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003364 """
Jon Hall0dd09952018-04-19 09:59:11 -07003365 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003366 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003367 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003368 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003369 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003370 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003371 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003372 cmdStr += " -j"
3373 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003374 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003375 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003376 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003377 except AssertionError:
3378 main.log.exception( "" )
3379 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003380 except TypeError:
3381 main.log.exception( self.name + ": Object not as expected" )
3382 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003383 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003384 main.log.error( self.name + ": EOF exception found" )
3385 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003386 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003387 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003388 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003389 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003390
kelvin-onlabd3b64892015-01-20 13:26:24 -08003391 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003392 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003393 CLI command to get the current leader for the Election test application
3394 NOTE: Requires installation of the onos-app-election feature
3395 Returns: Node IP of the leader if one exists
3396 None if none exists
3397 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003398 """
Jon Hall94fd0472014-12-08 11:52:42 -08003399 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003400 cmdStr = "election-test-leader"
3401 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003402 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003403 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003404 # Leader
3405 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003406 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003407 nodeSearch = re.search( leaderPattern, response )
3408 if nodeSearch:
3409 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003410 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003411 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003412 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003413 # no leader
3414 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003415 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003416 nullSearch = re.search( nullPattern, response )
3417 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003418 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003419 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003420 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003421 # error
Jon Hall0e240372018-05-02 11:21:57 -07003422 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003423 ": " + "unexpected response" )
3424 main.log.error( repr( response ) )
3425 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003426 except AssertionError:
3427 main.log.exception( "" )
3428 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003429 except TypeError:
3430 main.log.exception( self.name + ": Object not as expected" )
3431 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003432 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003433 main.log.error( self.name + ": EOF exception found" )
3434 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003435 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003436 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003437 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003438 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003439
kelvin-onlabd3b64892015-01-20 13:26:24 -08003440 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003441 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003442 CLI command to run for leadership of the Election test application.
3443 NOTE: Requires installation of the onos-app-election feature
3444 Returns: Main.TRUE on success
3445 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003446 """
Jon Hall94fd0472014-12-08 11:52:42 -08003447 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003448 cmdStr = "election-test-run"
3449 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003450 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003451 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003452 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003453 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003454 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003455 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003456 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003457 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003458 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003459 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003460 # error
Jon Hall0e240372018-05-02 11:21:57 -07003461 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003462 ": " + "unexpected response" )
3463 main.log.error( repr( response ) )
3464 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003465 except AssertionError:
3466 main.log.exception( "" )
3467 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003468 except TypeError:
3469 main.log.exception( self.name + ": Object not as expected" )
3470 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003471 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003472 main.log.error( self.name + ": EOF exception found" )
3473 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003474 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003475 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003476 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003477 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003478
kelvin-onlabd3b64892015-01-20 13:26:24 -08003479 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003480 """
Jon Hall94fd0472014-12-08 11:52:42 -08003481 * CLI command to withdraw the local node from leadership election for
3482 * the Election test application.
3483 #NOTE: Requires installation of the onos-app-election feature
3484 Returns: Main.TRUE on success
3485 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003486 """
Jon Hall94fd0472014-12-08 11:52:42 -08003487 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003488 cmdStr = "election-test-withdraw"
3489 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003490 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003491 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003492 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003493 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003494 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003495 if re.search( successPattern, response ):
3496 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003497 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003498 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003499 # error
Jon Hall0e240372018-05-02 11:21:57 -07003500 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003501 self.name + ": " + "unexpected response" )
3502 main.log.error( repr( response ) )
3503 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003504 except AssertionError:
3505 main.log.exception( "" )
3506 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003507 except TypeError:
3508 main.log.exception( self.name + ": Object not as expected" )
3509 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003510 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003511 main.log.error( self.name + ": EOF exception found" )
3512 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003513 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003514 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003515 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003516 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003517
kelvin8ec71442015-01-15 16:57:00 -08003518 def getDevicePortsEnabledCount( self, dpid ):
3519 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003520 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003521 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003522 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003523 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003524 cmdStr = "onos:ports -e " + dpid + " | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003525 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003526 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003527 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003528 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003529 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003530 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003531 return output
Jon Hallc6793552016-01-19 14:18:37 -08003532 except AssertionError:
3533 main.log.exception( "" )
3534 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003535 except TypeError:
3536 main.log.exception( self.name + ": Object not as expected" )
3537 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003538 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003539 main.log.error( self.name + ": EOF exception found" )
3540 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003541 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003542 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003543 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003544 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003545
kelvin8ec71442015-01-15 16:57:00 -08003546 def getDeviceLinksActiveCount( self, dpid ):
3547 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003548 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003549 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003550 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003551 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003552 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003553 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003554 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003555 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003556 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003557 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003558 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003559 return output
Jon Hallc6793552016-01-19 14:18:37 -08003560 except AssertionError:
3561 main.log.exception( "" )
3562 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003563 except TypeError:
3564 main.log.exception( self.name + ": Object not as expected" )
3565 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003566 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003567 main.log.error( self.name + ": EOF exception found" )
3568 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003569 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003570 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003571 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003572 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003573
kelvin8ec71442015-01-15 16:57:00 -08003574 def getAllIntentIds( self ):
3575 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003576 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003577 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003578 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003579 cmdStr = "onos:intents | grep id="
3580 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003581 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003582 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003583 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003584 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003585 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003586 return output
Jon Hallc6793552016-01-19 14:18:37 -08003587 except AssertionError:
3588 main.log.exception( "" )
3589 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003590 except TypeError:
3591 main.log.exception( self.name + ": Object not as expected" )
3592 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003593 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003594 main.log.error( self.name + ": EOF exception found" )
3595 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003596 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003597 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003598 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003599 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003600
Jon Hall73509952015-02-24 16:42:56 -08003601 def intentSummary( self ):
3602 """
Jon Hallefbd9792015-03-05 16:11:36 -08003603 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003604 """
3605 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003606 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003607 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003608 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003609 states.append( intent.get( 'state', None ) )
3610 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003611 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003612 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003613 except ( TypeError, ValueError ):
3614 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003615 return None
3616 except pexpect.EOF:
3617 main.log.error( self.name + ": EOF exception found" )
3618 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003619 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003620 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003621 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003622 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003623
Jon Hall61282e32015-03-19 11:34:11 -07003624 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003625 """
3626 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003627 Optional argument:
3628 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003629 """
Jon Hall63604932015-02-26 17:09:50 -08003630 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003631 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003632 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003633 cmdStr += " -j"
3634 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003635 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003636 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003637 return output
Jon Hallc6793552016-01-19 14:18:37 -08003638 except AssertionError:
3639 main.log.exception( "" )
3640 return None
Jon Hall63604932015-02-26 17:09:50 -08003641 except TypeError:
3642 main.log.exception( self.name + ": Object not as expected" )
3643 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003644 except pexpect.EOF:
3645 main.log.error( self.name + ": EOF exception found" )
3646 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003647 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003648 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003649 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003650 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003651
acsmarsa4a4d1e2015-07-10 16:01:24 -07003652 def leaderCandidates( self, jsonFormat=True ):
3653 """
3654 Returns the output of the leaders -c command.
3655 Optional argument:
3656 * jsonFormat - boolean indicating if you want output in json
3657 """
3658 try:
3659 cmdStr = "onos:leaders -c"
3660 if jsonFormat:
3661 cmdStr += " -j"
3662 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003663 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003664 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003665 return output
Jon Hallc6793552016-01-19 14:18:37 -08003666 except AssertionError:
3667 main.log.exception( "" )
3668 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003669 except TypeError:
3670 main.log.exception( self.name + ": Object not as expected" )
3671 return None
3672 except pexpect.EOF:
3673 main.log.error( self.name + ": EOF exception found" )
3674 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003675 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003676 except Exception:
3677 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003678 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003679
Jon Hallc6793552016-01-19 14:18:37 -08003680 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003681 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003682 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003683 topic parameter and an empty list if the topic doesn't exist
3684 If no leader is elected leader in the returned list will be "none"
3685 Returns None if there is a type error processing the json object
3686 """
3687 try:
Jon Hall6e709752016-02-01 13:38:46 -08003688 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003689 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003690 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003691 assert "Command not found:" not in rawOutput, rawOutput
3692 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003693 results = []
3694 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003695 if dict[ "topic" ] == topic:
3696 leader = dict[ "leader" ]
3697 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003698 results.append( leader )
3699 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003700 return results
Jon Hallc6793552016-01-19 14:18:37 -08003701 except AssertionError:
3702 main.log.exception( "" )
3703 return None
3704 except ( TypeError, ValueError ):
3705 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003706 return None
3707 except pexpect.EOF:
3708 main.log.error( self.name + ": EOF exception found" )
3709 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003710 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003711 except Exception:
3712 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003713 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003714
Jon Hall61282e32015-03-19 11:34:11 -07003715 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003716 """
3717 Returns the output of the intent Pending map.
3718 """
Jon Hall63604932015-02-26 17:09:50 -08003719 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003720 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003721 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003722 cmdStr += " -j"
3723 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003724 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003725 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003726 return output
Jon Hallc6793552016-01-19 14:18:37 -08003727 except AssertionError:
3728 main.log.exception( "" )
3729 return None
Jon Hall63604932015-02-26 17:09:50 -08003730 except TypeError:
3731 main.log.exception( self.name + ": Object not as expected" )
3732 return None
3733 except pexpect.EOF:
3734 main.log.error( self.name + ": EOF exception found" )
3735 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003736 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003737 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003738 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003739 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003740
Jon Hall2c8959e2016-12-16 12:17:34 -08003741 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003742 """
3743 Returns the output of the raft partitions command for ONOS.
3744 """
Jon Hall61282e32015-03-19 11:34:11 -07003745 # Sample JSON
3746 # {
3747 # "leader": "tcp://10.128.30.11:7238",
3748 # "members": [
3749 # "tcp://10.128.30.11:7238",
3750 # "tcp://10.128.30.17:7238",
3751 # "tcp://10.128.30.13:7238",
3752 # ],
3753 # "name": "p1",
3754 # "term": 3
3755 # },
Jon Hall63604932015-02-26 17:09:50 -08003756 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003757 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003758 if candidates:
3759 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003760 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003761 cmdStr += " -j"
3762 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003763 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003764 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003765 return output
Jon Hallc6793552016-01-19 14:18:37 -08003766 except AssertionError:
3767 main.log.exception( "" )
3768 return None
Jon Hall63604932015-02-26 17:09:50 -08003769 except TypeError:
3770 main.log.exception( self.name + ": Object not as expected" )
3771 return None
3772 except pexpect.EOF:
3773 main.log.error( self.name + ": EOF exception found" )
3774 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003775 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003776 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003777 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003778 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003779
Jon Halle9f909e2016-09-23 10:43:12 -07003780 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003781 """
3782 Returns the output of the apps command for ONOS. This command lists
3783 information about installed ONOS applications
3784 """
3785 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003786 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003787 # "description":"ONOS OpenFlow protocol southbound providers",
3788 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003789 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003790 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003791 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003792 if summary:
3793 cmdStr += " -s"
3794 if active:
3795 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003796 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003797 cmdStr += " -j"
3798 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003799 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003800 assert "Command not found:" not in output, output
3801 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003802 return output
Jon Hallbe379602015-03-24 13:39:32 -07003803 # FIXME: look at specific exceptions/Errors
3804 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003805 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003806 return None
3807 except TypeError:
3808 main.log.exception( self.name + ": Object not as expected" )
3809 return None
3810 except pexpect.EOF:
3811 main.log.error( self.name + ": EOF exception found" )
3812 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003813 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003814 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003815 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003816 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003817
You Wangcdc51fe2018-08-12 17:14:56 -07003818 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003819 """
3820 Uses the onos:apps cli command to return the status of an application.
3821 Returns:
3822 "ACTIVE" - If app is installed and activated
3823 "INSTALLED" - If app is installed and deactivated
3824 "UNINSTALLED" - If app is not installed
3825 None - on error
3826 """
Jon Hall146f1522015-03-24 15:33:24 -07003827 try:
3828 if not isinstance( appName, types.StringType ):
3829 main.log.error( self.name + ".appStatus(): appName must be" +
3830 " a string" )
3831 return None
3832 output = self.apps( jsonFormat=True )
3833 appsJson = json.loads( output )
3834 state = None
3835 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003836 if appName == app.get( 'name' ):
3837 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003838 break
3839 if state == "ACTIVE" or state == "INSTALLED":
3840 return state
3841 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003842 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003843 return "UNINSTALLED"
3844 elif state:
3845 main.log.error( "Unexpected state from 'onos:apps': " +
3846 str( state ) )
3847 return state
Jon Hallc6793552016-01-19 14:18:37 -08003848 except ( TypeError, ValueError ):
3849 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003850 return None
3851 except pexpect.EOF:
3852 main.log.error( self.name + ": EOF exception found" )
3853 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003854 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003855 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003856 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003857 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003858
Jon Hallbe379602015-03-24 13:39:32 -07003859 def app( self, appName, option ):
3860 """
3861 Interacts with the app command for ONOS. This command manages
3862 application inventory.
3863 """
Jon Hallbe379602015-03-24 13:39:32 -07003864 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003865 # Validate argument types
3866 valid = True
3867 if not isinstance( appName, types.StringType ):
3868 main.log.error( self.name + ".app(): appName must be a " +
3869 "string" )
3870 valid = False
3871 if not isinstance( option, types.StringType ):
3872 main.log.error( self.name + ".app(): option must be a string" )
3873 valid = False
3874 if not valid:
3875 return main.FALSE
3876 # Validate Option
3877 option = option.lower()
3878 # NOTE: Install may become a valid option
3879 if option == "activate":
3880 pass
3881 elif option == "deactivate":
3882 pass
3883 elif option == "uninstall":
3884 pass
3885 else:
3886 # Invalid option
3887 main.log.error( "The ONOS app command argument only takes " +
3888 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003889 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003890 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003891 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003892 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003893 assert output is not None, "Error in sendline"
3894 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003895 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003896 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003897 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003898 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003899 elif "No such application" in output:
3900 main.log.error( "The application '" + appName +
3901 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003902 return main.FALSE
3903 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003904 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003905 str( output ) )
3906 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003907 elif "Unsupported command:" in output:
3908 main.log.error( "Incorrect command given to 'app': " +
3909 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003910 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003911 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003912 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003913 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003914 except AssertionError:
3915 main.log.exception( self.name + ": AssertionError exception found" )
3916 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003917 except TypeError:
3918 main.log.exception( self.name + ": Object not as expected" )
3919 return main.ERROR
3920 except pexpect.EOF:
3921 main.log.error( self.name + ": EOF exception found" )
3922 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003923 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003924 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003925 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003926 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003927
Jon Hallbd16b922015-03-26 17:53:15 -07003928 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003929 """
3930 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003931 appName is the hierarchical app name, not the feature name
3932 If check is True, method will check the status of the app after the
3933 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003934 Returns main.TRUE if the command was successfully sent
3935 main.FALSE if the cli responded with an error or given
3936 incorrect input
3937 """
3938 try:
3939 if not isinstance( appName, types.StringType ):
3940 main.log.error( self.name + ".activateApp(): appName must be" +
3941 " a string" )
3942 return main.FALSE
3943 status = self.appStatus( appName )
3944 if status == "INSTALLED":
3945 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003946 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003947 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003948 status = self.appStatus( appName )
3949 if status == "ACTIVE":
3950 return main.TRUE
3951 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003952 main.log.debug( "The state of application " +
3953 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003954 time.sleep( 1 )
3955 return main.FALSE
3956 else: # not 'check' or command didn't succeed
3957 return response
Jon Hall146f1522015-03-24 15:33:24 -07003958 elif status == "ACTIVE":
3959 return main.TRUE
3960 elif status == "UNINSTALLED":
3961 main.log.error( self.name + ": Tried to activate the " +
3962 "application '" + appName + "' which is not " +
3963 "installed." )
3964 else:
3965 main.log.error( "Unexpected return value from appStatus: " +
3966 str( status ) )
3967 return main.ERROR
3968 except TypeError:
3969 main.log.exception( self.name + ": Object not as expected" )
3970 return main.ERROR
3971 except pexpect.EOF:
3972 main.log.error( self.name + ": EOF exception found" )
3973 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003974 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003975 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003976 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003977 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003978
Jon Hallbd16b922015-03-26 17:53:15 -07003979 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003980 """
3981 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003982 appName is the hierarchical app name, not the feature name
3983 If check is True, method will check the status of the app after the
3984 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003985 Returns main.TRUE if the command was successfully sent
3986 main.FALSE if the cli responded with an error or given
3987 incorrect input
3988 """
3989 try:
3990 if not isinstance( appName, types.StringType ):
3991 main.log.error( self.name + ".deactivateApp(): appName must " +
3992 "be a string" )
3993 return main.FALSE
3994 status = self.appStatus( appName )
3995 if status == "INSTALLED":
3996 return main.TRUE
3997 elif status == "ACTIVE":
3998 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003999 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004000 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004001 status = self.appStatus( appName )
4002 if status == "INSTALLED":
4003 return main.TRUE
4004 else:
4005 time.sleep( 1 )
4006 return main.FALSE
4007 else: # not check or command didn't succeed
4008 return response
Jon Hall146f1522015-03-24 15:33:24 -07004009 elif status == "UNINSTALLED":
4010 main.log.warn( self.name + ": Tried to deactivate the " +
4011 "application '" + appName + "' which is not " +
4012 "installed." )
4013 return main.TRUE
4014 else:
4015 main.log.error( "Unexpected return value from appStatus: " +
4016 str( status ) )
4017 return main.ERROR
4018 except TypeError:
4019 main.log.exception( self.name + ": Object not as expected" )
4020 return main.ERROR
4021 except pexpect.EOF:
4022 main.log.error( self.name + ": EOF exception found" )
4023 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004024 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004025 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004026 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004027 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004028
Jon Hallbd16b922015-03-26 17:53:15 -07004029 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004030 """
4031 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004032 appName is the hierarchical app name, not the feature name
4033 If check is True, method will check the status of the app after the
4034 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004035 Returns main.TRUE if the command was successfully sent
4036 main.FALSE if the cli responded with an error or given
4037 incorrect input
4038 """
4039 # TODO: check with Thomas about the state machine for apps
4040 try:
4041 if not isinstance( appName, types.StringType ):
4042 main.log.error( self.name + ".uninstallApp(): appName must " +
4043 "be a string" )
4044 return main.FALSE
4045 status = self.appStatus( appName )
4046 if status == "INSTALLED":
4047 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004048 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004049 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004050 status = self.appStatus( appName )
4051 if status == "UNINSTALLED":
4052 return main.TRUE
4053 else:
4054 time.sleep( 1 )
4055 return main.FALSE
4056 else: # not check or command didn't succeed
4057 return response
Jon Hall146f1522015-03-24 15:33:24 -07004058 elif status == "ACTIVE":
4059 main.log.warn( self.name + ": Tried to uninstall the " +
4060 "application '" + appName + "' which is " +
4061 "currently active." )
4062 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004063 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004064 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004065 status = self.appStatus( appName )
4066 if status == "UNINSTALLED":
4067 return main.TRUE
4068 else:
4069 time.sleep( 1 )
4070 return main.FALSE
4071 else: # not check or command didn't succeed
4072 return response
Jon Hall146f1522015-03-24 15:33:24 -07004073 elif status == "UNINSTALLED":
4074 return main.TRUE
4075 else:
4076 main.log.error( "Unexpected return value from appStatus: " +
4077 str( status ) )
4078 return main.ERROR
4079 except TypeError:
4080 main.log.exception( self.name + ": Object not as expected" )
4081 return main.ERROR
4082 except pexpect.EOF:
4083 main.log.error( self.name + ": EOF exception found" )
4084 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004085 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004086 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004087 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004088 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004089
4090 def appIDs( self, jsonFormat=True ):
4091 """
4092 Show the mappings between app id and app names given by the 'app-ids'
4093 cli command
4094 """
4095 try:
4096 cmdStr = "app-ids"
4097 if jsonFormat:
4098 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004099 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004100 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004101 assert "Command not found:" not in output, output
4102 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004103 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004104 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004105 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004106 return None
4107 except TypeError:
4108 main.log.exception( self.name + ": Object not as expected" )
4109 return None
4110 except pexpect.EOF:
4111 main.log.error( self.name + ": EOF exception found" )
4112 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004113 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004114 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004115 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004116 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004117
4118 def appToIDCheck( self ):
4119 """
4120 This method will check that each application's ID listed in 'apps' is
4121 the same as the ID listed in 'app-ids'. The check will also check that
4122 there are no duplicate IDs issued. Note that an app ID should be
4123 a globaly unique numerical identifier for app/app-like features. Once
4124 an ID is registered, the ID is never freed up so that if an app is
4125 reinstalled it will have the same ID.
4126
4127 Returns: main.TRUE if the check passes and
4128 main.FALSE if the check fails or
4129 main.ERROR if there is some error in processing the test
4130 """
4131 try:
Jon Hall0e240372018-05-02 11:21:57 -07004132 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004133 rawJson = self.appIDs( jsonFormat=True )
4134 if rawJson:
4135 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004136 else:
Jon Hall0e240372018-05-02 11:21:57 -07004137 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4138 return main.FALSE
4139
4140 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004141 rawJson = self.apps( jsonFormat=True )
4142 if rawJson:
4143 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004144 else:
Jon Hallc6793552016-01-19 14:18:37 -08004145 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004146 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004147
Jon Hallbd16b922015-03-26 17:53:15 -07004148 result = main.TRUE
4149 for app in apps:
4150 appID = app.get( 'id' )
4151 if appID is None:
4152 main.log.error( "Error parsing app: " + str( app ) )
4153 result = main.FALSE
4154 appName = app.get( 'name' )
4155 if appName is None:
4156 main.log.error( "Error parsing app: " + str( app ) )
4157 result = main.FALSE
4158 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004159 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004160 if not current: # if ids doesn't have this id
4161 result = main.FALSE
4162 main.log.error( "'app-ids' does not have the ID for " +
4163 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004164 main.log.debug( "apps command returned: " + str( app ) +
4165 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004166 elif len( current ) > 1:
4167 # there is more than one app with this ID
4168 result = main.FALSE
4169 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004170 elif not current[ 0 ][ 'name' ] == appName:
4171 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004172 result = main.FALSE
4173 main.log.error( "'app-ids' has " + str( currentName ) +
4174 " registered under id:" + str( appID ) +
4175 " but 'apps' has " + str( appName ) )
4176 else:
4177 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004178
Jon Hallbd16b922015-03-26 17:53:15 -07004179 # now make sure that app-ids has no duplicates
4180 idsList = []
4181 namesList = []
4182 for item in ids:
4183 idsList.append( item[ 'id' ] )
4184 namesList.append( item[ 'name' ] )
4185 if len( idsList ) != len( set( idsList ) ) or\
4186 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004187 main.log.error( "'app-ids' has some duplicate entries: \n"
4188 + json.dumps( ids,
4189 sort_keys=True,
4190 indent=4,
4191 separators=( ',', ': ' ) ) )
4192 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004193 return result
Jon Hallc6793552016-01-19 14:18:37 -08004194 except ( TypeError, ValueError ):
4195 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004196 return main.ERROR
4197 except pexpect.EOF:
4198 main.log.error( self.name + ": EOF exception found" )
4199 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004200 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004201 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004202 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004203 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004204
Jon Hallfb760a02015-04-13 15:35:03 -07004205 def getCfg( self, component=None, propName=None, short=False,
4206 jsonFormat=True ):
4207 """
4208 Get configuration settings from onos cli
4209 Optional arguments:
4210 component - Optionally only list configurations for a specific
4211 component. If None, all components with configurations
4212 are displayed. Case Sensitive string.
4213 propName - If component is specified, propName option will show
4214 only this specific configuration from that component.
4215 Case Sensitive string.
4216 jsonFormat - Returns output as json. Note that this will override
4217 the short option
4218 short - Short, less verbose, version of configurations.
4219 This is overridden by the json option
4220 returns:
4221 Output from cli as a string or None on error
4222 """
4223 try:
4224 baseStr = "cfg"
4225 cmdStr = " get"
4226 componentStr = ""
4227 if component:
4228 componentStr += " " + component
4229 if propName:
4230 componentStr += " " + propName
4231 if jsonFormat:
4232 baseStr += " -j"
4233 elif short:
4234 baseStr += " -s"
4235 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004236 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004237 assert "Command not found:" not in output, output
4238 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004239 return output
4240 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004241 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004242 return None
4243 except TypeError:
4244 main.log.exception( self.name + ": Object not as expected" )
4245 return None
4246 except pexpect.EOF:
4247 main.log.error( self.name + ": EOF exception found" )
4248 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004249 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004250 except Exception:
4251 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004252 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004253
4254 def setCfg( self, component, propName, value=None, check=True ):
4255 """
4256 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004257 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004258 component - The case sensitive name of the component whose
4259 property is to be set
4260 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004261 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004262 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004263 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004264 check - Boolean, Check whether the option was successfully set this
4265 only applies when a value is given.
4266 returns:
4267 main.TRUE on success or main.FALSE on failure. If check is False,
4268 will return main.TRUE unless there is an error
4269 """
4270 try:
4271 baseStr = "cfg"
4272 cmdStr = " set " + str( component ) + " " + str( propName )
4273 if value is not None:
4274 cmdStr += " " + str( value )
4275 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004276 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004277 assert "Command not found:" not in output, output
4278 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004279 if value and check:
4280 results = self.getCfg( component=str( component ),
4281 propName=str( propName ),
4282 jsonFormat=True )
4283 # Check if current value is what we just set
4284 try:
4285 jsonOutput = json.loads( results )
4286 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004287 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004288 main.log.exception( "Error parsing cfg output" )
4289 main.log.error( "output:" + repr( results ) )
4290 return main.FALSE
4291 if current == str( value ):
4292 return main.TRUE
4293 return main.FALSE
4294 return main.TRUE
4295 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004296 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004297 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004298 except ( TypeError, ValueError ):
4299 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004300 return main.FALSE
4301 except pexpect.EOF:
4302 main.log.error( self.name + ": EOF exception found" )
4303 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004304 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004305 except Exception:
4306 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004307 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004308
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004309 def distPrimitivesSend( self, cmd ):
4310 """
4311 Function to handle sending cli commands for the distributed primitives test app
4312
4313 This command will catch some exceptions and retry the command on some
4314 specific store exceptions.
4315
4316 Required arguments:
4317 cmd - The command to send to the cli
4318 returns:
4319 string containing the cli output
4320 None on Error
4321 """
4322 try:
4323 output = self.sendline( cmd )
4324 try:
4325 assert output is not None, "Error in sendline"
4326 # TODO: Maybe make this less hardcoded
4327 # ConsistentMap Exceptions
4328 assert "org.onosproject.store.service" not in output
4329 # Node not leader
4330 assert "java.lang.IllegalStateException" not in output
4331 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004332 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004333 "command: " + str( output ) )
4334 retryTime = 30 # Conservative time, given by Madan
4335 main.log.info( "Waiting " + str( retryTime ) +
4336 "seconds before retrying." )
4337 time.sleep( retryTime ) # Due to change in mastership
4338 output = self.sendline( cmd )
4339 assert output is not None, "Error in sendline"
4340 assert "Command not found:" not in output, output
4341 assert "Error executing command" not in output, output
4342 main.log.info( self.name + ": " + output )
4343 return output
4344 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004345 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004346 return None
4347 except TypeError:
4348 main.log.exception( self.name + ": Object not as expected" )
4349 return None
4350 except pexpect.EOF:
4351 main.log.error( self.name + ": EOF exception found" )
4352 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004353 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004354 except Exception:
4355 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004356 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004357
Jon Hall390696c2015-05-05 17:13:41 -07004358 def setTestAdd( self, setName, values ):
4359 """
4360 CLI command to add elements to a distributed set.
4361 Arguments:
4362 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004363 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004364 Example usages:
4365 setTestAdd( "set1", "a b c" )
4366 setTestAdd( "set2", "1" )
4367 returns:
4368 main.TRUE on success OR
4369 main.FALSE if elements were already in the set OR
4370 main.ERROR on error
4371 """
4372 try:
4373 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004374 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004375 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4376 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004377 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004378 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004379 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004380 return main.FALSE
4381 else:
4382 main.log.error( self.name + ": setTestAdd did not" +
4383 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004384 main.log.debug( self.name + " actual: " + repr( output ) )
4385 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004386 except TypeError:
4387 main.log.exception( self.name + ": Object not as expected" )
4388 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004389 except Exception:
4390 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004391 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004392
4393 def setTestRemove( self, setName, values, clear=False, retain=False ):
4394 """
4395 CLI command to remove elements from a distributed set.
4396 Required arguments:
4397 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004398 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004399 Optional arguments:
4400 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004401 retain - Retain only the given values. (intersection of the
4402 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004403 returns:
4404 main.TRUE on success OR
4405 main.FALSE if the set was not changed OR
4406 main.ERROR on error
4407 """
4408 try:
4409 cmdStr = "set-test-remove "
4410 if clear:
4411 cmdStr += "-c " + str( setName )
4412 elif retain:
4413 cmdStr += "-r " + str( setName ) + " " + str( values )
4414 else:
4415 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004416 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004417 if clear:
4418 pattern = "Set " + str( setName ) + " cleared"
4419 if re.search( pattern, output ):
4420 return main.TRUE
4421 elif retain:
4422 positivePattern = str( setName ) + " was pruned to contain " +\
4423 "only elements of set \[(.*)\]"
4424 negativePattern = str( setName ) + " was not changed by " +\
4425 "retaining only elements of the set " +\
4426 "\[(.*)\]"
4427 if re.search( positivePattern, output ):
4428 return main.TRUE
4429 elif re.search( negativePattern, output ):
4430 return main.FALSE
4431 else:
4432 positivePattern = "\[(.*)\] was removed from the set " +\
4433 str( setName )
4434 if ( len( values.split() ) == 1 ):
4435 negativePattern = "\[(.*)\] was not in set " +\
4436 str( setName )
4437 else:
4438 negativePattern = "No element of \[(.*)\] was in set " +\
4439 str( setName )
4440 if re.search( positivePattern, output ):
4441 return main.TRUE
4442 elif re.search( negativePattern, output ):
4443 return main.FALSE
4444 main.log.error( self.name + ": setTestRemove did not" +
4445 " match expected output" )
4446 main.log.debug( self.name + " expected: " + pattern )
4447 main.log.debug( self.name + " actual: " + repr( output ) )
4448 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004449 except TypeError:
4450 main.log.exception( self.name + ": Object not as expected" )
4451 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004452 except Exception:
4453 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004454 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004455
4456 def setTestGet( self, setName, values="" ):
4457 """
4458 CLI command to get the elements in a distributed set.
4459 Required arguments:
4460 setName - The name of the set to remove from.
4461 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004462 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004463 returns:
4464 main.ERROR on error OR
4465 A list of elements in the set if no optional arguments are
4466 supplied OR
4467 A tuple containing the list then:
4468 main.FALSE if the given values are not in the set OR
4469 main.TRUE if the given values are in the set OR
4470 """
4471 try:
4472 values = str( values ).strip()
4473 setName = str( setName ).strip()
4474 length = len( values.split() )
4475 containsCheck = None
4476 # Patterns to match
4477 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004478 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004479 containsTrue = "Set " + setName + " contains the value " + values
4480 containsFalse = "Set " + setName + " did not contain the value " +\
4481 values
4482 containsAllTrue = "Set " + setName + " contains the the subset " +\
4483 setPattern
4484 containsAllFalse = "Set " + setName + " did not contain the the" +\
4485 " subset " + setPattern
4486
4487 cmdStr = "set-test-get "
4488 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004489 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004490 if length == 0:
4491 match = re.search( pattern, output )
4492 else: # if given values
4493 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004494 patternTrue = pattern + "\r\n" + containsTrue
4495 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004496 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004497 patternTrue = pattern + "\r\n" + containsAllTrue
4498 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004499 matchTrue = re.search( patternTrue, output )
4500 matchFalse = re.search( patternFalse, output )
4501 if matchTrue:
4502 containsCheck = main.TRUE
4503 match = matchTrue
4504 elif matchFalse:
4505 containsCheck = main.FALSE
4506 match = matchFalse
4507 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004508 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004509 "expected output" )
4510 main.log.debug( self.name + " expected: " + pattern )
4511 main.log.debug( self.name + " actual: " + repr( output ) )
4512 match = None
4513 if match:
4514 setMatch = match.group( 1 )
4515 if setMatch == '':
4516 setList = []
4517 else:
4518 setList = setMatch.split( ", " )
4519 if length > 0:
4520 return ( setList, containsCheck )
4521 else:
4522 return setList
4523 else: # no match
4524 main.log.error( self.name + ": setTestGet did not" +
4525 " match expected output" )
4526 main.log.debug( self.name + " expected: " + pattern )
4527 main.log.debug( self.name + " actual: " + repr( output ) )
4528 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004529 except TypeError:
4530 main.log.exception( self.name + ": Object not as expected" )
4531 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004532 except Exception:
4533 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004534 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004535
4536 def setTestSize( self, setName ):
4537 """
4538 CLI command to get the elements in a distributed set.
4539 Required arguments:
4540 setName - The name of the set to remove from.
4541 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004542 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004543 None on error
4544 """
4545 try:
4546 # TODO: Should this check against the number of elements returned
4547 # and then return true/false based on that?
4548 setName = str( setName ).strip()
4549 # Patterns to match
4550 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004551 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004552 setPattern
4553 cmdStr = "set-test-get -s "
4554 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004555 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004556 if output:
4557 match = re.search( pattern, output )
4558 if match:
4559 setSize = int( match.group( 1 ) )
4560 setMatch = match.group( 2 )
4561 if len( setMatch.split() ) == setSize:
4562 main.log.info( "The size returned by " + self.name +
4563 " matches the number of elements in " +
4564 "the returned set" )
4565 else:
4566 main.log.error( "The size returned by " + self.name +
4567 " does not match the number of " +
4568 "elements in the returned set." )
4569 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004570 else: # no match
4571 main.log.error( self.name + ": setTestGet did not" +
4572 " match expected output" )
4573 main.log.debug( self.name + " expected: " + pattern )
4574 main.log.debug( self.name + " actual: " + repr( output ) )
4575 return None
Jon Hall390696c2015-05-05 17:13:41 -07004576 except TypeError:
4577 main.log.exception( self.name + ": Object not as expected" )
4578 return None
Jon Hall390696c2015-05-05 17:13:41 -07004579 except Exception:
4580 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004581 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004582
Jon Hall80daded2015-05-27 16:07:00 -07004583 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004584 """
4585 Command to list the various counters in the system.
4586 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004587 if jsonFormat, a string of the json object returned by the cli
4588 command
4589 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004590 None on error
4591 """
Jon Hall390696c2015-05-05 17:13:41 -07004592 try:
Jon Hall390696c2015-05-05 17:13:41 -07004593 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004594 if jsonFormat:
4595 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004596 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004597 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004598 assert "Command not found:" not in output, output
4599 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004600 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004601 return output
Jon Hall390696c2015-05-05 17:13:41 -07004602 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004603 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004604 return None
Jon Hall390696c2015-05-05 17:13:41 -07004605 except TypeError:
4606 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004607 return None
Jon Hall390696c2015-05-05 17:13:41 -07004608 except pexpect.EOF:
4609 main.log.error( self.name + ": EOF exception found" )
4610 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004611 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004612 except Exception:
4613 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004614 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004615
Jon Hall935db192016-04-19 00:22:04 -07004616 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004617 """
Jon Halle1a3b752015-07-22 13:02:46 -07004618 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004619 Required arguments:
4620 counter - The name of the counter to increment.
4621 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004622 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004623 returns:
4624 integer value of the counter or
4625 None on Error
4626 """
4627 try:
4628 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004629 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004630 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004631 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004632 if delta != 1:
4633 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004634 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004635 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004636 match = re.search( pattern, output )
4637 if match:
4638 return int( match.group( 1 ) )
4639 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004640 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004641 " match expected output." )
4642 main.log.debug( self.name + " expected: " + pattern )
4643 main.log.debug( self.name + " actual: " + repr( output ) )
4644 return None
Jon Hall390696c2015-05-05 17:13:41 -07004645 except TypeError:
4646 main.log.exception( self.name + ": Object not as expected" )
4647 return None
Jon Hall390696c2015-05-05 17:13:41 -07004648 except Exception:
4649 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004650 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004651
Jon Hall935db192016-04-19 00:22:04 -07004652 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004653 """
4654 CLI command to get a distributed counter then add a delta to it.
4655 Required arguments:
4656 counter - The name of the counter to increment.
4657 Optional arguments:
4658 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004659 returns:
4660 integer value of the counter or
4661 None on Error
4662 """
4663 try:
4664 counter = str( counter )
4665 delta = int( delta )
4666 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004667 cmdStr += counter
4668 if delta != 1:
4669 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004670 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004671 pattern = counter + " was updated to (-?\d+)"
4672 match = re.search( pattern, output )
4673 if match:
4674 return int( match.group( 1 ) )
4675 else:
4676 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4677 " match expected output." )
4678 main.log.debug( self.name + " expected: " + pattern )
4679 main.log.debug( self.name + " actual: " + repr( output ) )
4680 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004681 except TypeError:
4682 main.log.exception( self.name + ": Object not as expected" )
4683 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004684 except Exception:
4685 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004686 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004687
4688 def valueTestGet( self, valueName ):
4689 """
4690 CLI command to get the value of an atomic value.
4691 Required arguments:
4692 valueName - The name of the value to get.
4693 returns:
4694 string value of the value or
4695 None on Error
4696 """
4697 try:
4698 valueName = str( valueName )
4699 cmdStr = "value-test "
4700 operation = "get"
4701 cmdStr = "value-test {} {}".format( valueName,
4702 operation )
4703 output = self.distPrimitivesSend( cmdStr )
4704 pattern = "(\w+)"
4705 match = re.search( pattern, output )
4706 if match:
4707 return match.group( 1 )
4708 else:
4709 main.log.error( self.name + ": valueTestGet did not" +
4710 " match expected output." )
4711 main.log.debug( self.name + " expected: " + pattern )
4712 main.log.debug( self.name + " actual: " + repr( output ) )
4713 return None
4714 except TypeError:
4715 main.log.exception( self.name + ": Object not as expected" )
4716 return None
4717 except Exception:
4718 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004719 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004720
4721 def valueTestSet( self, valueName, newValue ):
4722 """
4723 CLI command to set the value of an atomic value.
4724 Required arguments:
4725 valueName - The name of the value to set.
4726 newValue - The value to assign to the given value.
4727 returns:
4728 main.TRUE on success or
4729 main.ERROR on Error
4730 """
4731 try:
4732 valueName = str( valueName )
4733 newValue = str( newValue )
4734 operation = "set"
4735 cmdStr = "value-test {} {} {}".format( valueName,
4736 operation,
4737 newValue )
4738 output = self.distPrimitivesSend( cmdStr )
4739 if output is not None:
4740 return main.TRUE
4741 else:
4742 return main.ERROR
4743 except TypeError:
4744 main.log.exception( self.name + ": Object not as expected" )
4745 return main.ERROR
4746 except Exception:
4747 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004748 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004749
4750 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4751 """
4752 CLI command to compareAndSet the value of an atomic value.
4753 Required arguments:
4754 valueName - The name of the value.
4755 oldValue - Compare the current value of the atomic value to this
4756 newValue - If the value equals oldValue, set the value to newValue
4757 returns:
4758 main.TRUE on success or
4759 main.FALSE on failure or
4760 main.ERROR on Error
4761 """
4762 try:
4763 valueName = str( valueName )
4764 oldValue = str( oldValue )
4765 newValue = str( newValue )
4766 operation = "compareAndSet"
4767 cmdStr = "value-test {} {} {} {}".format( valueName,
4768 operation,
4769 oldValue,
4770 newValue )
4771 output = self.distPrimitivesSend( cmdStr )
4772 pattern = "(\w+)"
4773 match = re.search( pattern, output )
4774 if match:
4775 result = match.group( 1 )
4776 if result == "true":
4777 return main.TRUE
4778 elif result == "false":
4779 return main.FALSE
4780 else:
4781 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4782 " match expected output." )
4783 main.log.debug( self.name + " expected: " + pattern )
4784 main.log.debug( self.name + " actual: " + repr( output ) )
4785 return main.ERROR
4786 except TypeError:
4787 main.log.exception( self.name + ": Object not as expected" )
4788 return main.ERROR
4789 except Exception:
4790 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004791 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004792
4793 def valueTestGetAndSet( self, valueName, newValue ):
4794 """
4795 CLI command to getAndSet the value of an atomic value.
4796 Required arguments:
4797 valueName - The name of the value to get.
4798 newValue - The value to assign to the given value
4799 returns:
4800 string value of the value or
4801 None on Error
4802 """
4803 try:
4804 valueName = str( valueName )
4805 cmdStr = "value-test "
4806 operation = "getAndSet"
4807 cmdStr += valueName + " " + operation
4808 cmdStr = "value-test {} {} {}".format( valueName,
4809 operation,
4810 newValue )
4811 output = self.distPrimitivesSend( cmdStr )
4812 pattern = "(\w+)"
4813 match = re.search( pattern, output )
4814 if match:
4815 return match.group( 1 )
4816 else:
4817 main.log.error( self.name + ": valueTestGetAndSet did not" +
4818 " match expected output." )
4819 main.log.debug( self.name + " expected: " + pattern )
4820 main.log.debug( self.name + " actual: " + repr( output ) )
4821 return None
4822 except TypeError:
4823 main.log.exception( self.name + ": Object not as expected" )
4824 return None
4825 except Exception:
4826 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004827 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004828
4829 def valueTestDestroy( self, valueName ):
4830 """
4831 CLI command to destroy an atomic value.
4832 Required arguments:
4833 valueName - The name of the value to destroy.
4834 returns:
4835 main.TRUE on success or
4836 main.ERROR on Error
4837 """
4838 try:
4839 valueName = str( valueName )
4840 cmdStr = "value-test "
4841 operation = "destroy"
4842 cmdStr += valueName + " " + operation
4843 output = self.distPrimitivesSend( cmdStr )
4844 if output is not None:
4845 return main.TRUE
4846 else:
4847 return main.ERROR
4848 except TypeError:
4849 main.log.exception( self.name + ": Object not as expected" )
4850 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004851 except Exception:
4852 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004853 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004854
YPZhangfebf7302016-05-24 16:45:56 -07004855 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004856 """
4857 Description: Execute summary command in onos
4858 Returns: json object ( summary -j ), returns main.FALSE if there is
4859 no output
4860
4861 """
4862 try:
4863 cmdStr = "summary"
4864 if jsonFormat:
4865 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004866 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004867 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004868 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004869 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004870 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004871 if not handle:
4872 main.log.error( self.name + ": There is no output in " +
4873 "summary command" )
4874 return main.FALSE
4875 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004876 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004877 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004878 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004879 except TypeError:
4880 main.log.exception( self.name + ": Object not as expected" )
4881 return None
4882 except pexpect.EOF:
4883 main.log.error( self.name + ": EOF exception found" )
4884 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004885 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004886 except Exception:
4887 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004888 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004889
Jon Hall935db192016-04-19 00:22:04 -07004890 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004891 """
4892 CLI command to get the value of a key in a consistent map using
4893 transactions. This a test function and can only get keys from the
4894 test map hard coded into the cli command
4895 Required arguments:
4896 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004897 returns:
4898 The string value of the key or
4899 None on Error
4900 """
4901 try:
4902 keyName = str( keyName )
4903 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004904 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004905 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004906 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4907 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004908 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004909 return None
4910 else:
4911 match = re.search( pattern, output )
4912 if match:
4913 return match.groupdict()[ 'value' ]
4914 else:
4915 main.log.error( self.name + ": transactionlMapGet did not" +
4916 " match expected output." )
4917 main.log.debug( self.name + " expected: " + pattern )
4918 main.log.debug( self.name + " actual: " + repr( output ) )
4919 return None
4920 except TypeError:
4921 main.log.exception( self.name + ": Object not as expected" )
4922 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004923 except Exception:
4924 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004925 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004926
Jon Hall935db192016-04-19 00:22:04 -07004927 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004928 """
4929 CLI command to put a value into 'numKeys' number of keys in a
4930 consistent map using transactions. This a test function and can only
4931 put into keys named 'Key#' of the test map hard coded into the cli command
4932 Required arguments:
4933 numKeys - Number of keys to add the value to
4934 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004935 returns:
4936 A dictionary whose keys are the name of the keys put into the map
4937 and the values of the keys are dictionaries whose key-values are
4938 'value': value put into map and optionaly
4939 'oldValue': Previous value in the key or
4940 None on Error
4941
4942 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004943 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4944 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004945 """
4946 try:
4947 numKeys = str( numKeys )
4948 value = str( value )
4949 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004950 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004951 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004952 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4953 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4954 results = {}
4955 for line in output.splitlines():
4956 new = re.search( newPattern, line )
4957 updated = re.search( updatedPattern, line )
4958 if new:
4959 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4960 elif updated:
4961 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004962 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004963 else:
4964 main.log.error( self.name + ": transactionlMapGet did not" +
4965 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004966 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4967 newPattern,
4968 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004969 main.log.debug( self.name + " actual: " + repr( output ) )
4970 return results
Jon Hall0e240372018-05-02 11:21:57 -07004971 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004972 main.log.exception( self.name + ": Object not as expected" )
4973 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004974 except Exception:
4975 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004976 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004977
acsmarsdaea66c2015-09-03 11:44:06 -07004978 def maps( self, jsonFormat=True ):
4979 """
4980 Description: Returns result of onos:maps
4981 Optional:
4982 * jsonFormat: enable json formatting of output
4983 """
4984 try:
4985 cmdStr = "maps"
4986 if jsonFormat:
4987 cmdStr += " -j"
4988 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004989 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004990 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004991 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004992 except AssertionError:
4993 main.log.exception( "" )
4994 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004995 except TypeError:
4996 main.log.exception( self.name + ": Object not as expected" )
4997 return None
4998 except pexpect.EOF:
4999 main.log.error( self.name + ": EOF exception found" )
5000 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005001 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07005002 except Exception:
5003 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005004 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005005
5006 def getSwController( self, uri, jsonFormat=True ):
5007 """
5008 Descrition: Gets the controller information from the device
5009 """
5010 try:
5011 cmd = "device-controllers "
5012 if jsonFormat:
5013 cmd += "-j "
5014 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07005015 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005016 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005017 return response
Jon Hallc6793552016-01-19 14:18:37 -08005018 except AssertionError:
5019 main.log.exception( "" )
5020 return None
GlennRC050596c2015-11-18 17:06:41 -08005021 except TypeError:
5022 main.log.exception( self.name + ": Object not as expected" )
5023 return None
5024 except pexpect.EOF:
5025 main.log.error( self.name + ": EOF exception found" )
5026 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005027 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005028 except Exception:
5029 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005030 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005031
5032 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
5033 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005034 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08005035
5036 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005037 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08005038 ip - String or List: The ip address of the controller.
5039 This parameter can be formed in a couple of different ways.
5040 VALID:
5041 10.0.0.1 - just the ip address
5042 tcp:10.0.0.1 - the protocol and the ip address
5043 tcp:10.0.0.1:6653 - the protocol and port can be specified,
5044 so that you can add controllers with different
5045 protocols and ports
5046 INVALID:
5047 10.0.0.1:6653 - this is not supported by ONOS
5048
5049 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
5050 port - The port number.
5051 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
5052
5053 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
5054 """
5055 try:
5056 cmd = "device-setcontrollers"
5057
5058 if jsonFormat:
5059 cmd += " -j"
5060 cmd += " " + uri
5061 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005062 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08005063 for item in ip:
5064 if ":" in item:
5065 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005066 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08005067 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005068 elif "." in sitem[ 1 ]:
5069 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08005070 else:
5071 main.log.error( "Malformed entry: " + item )
5072 raise TypeError
5073 else:
5074 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08005075 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07005076 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005077 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005078 if "Error" in response:
5079 main.log.error( response )
5080 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005081 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005082 except AssertionError:
5083 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005084 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005085 except TypeError:
5086 main.log.exception( self.name + ": Object not as expected" )
5087 return main.FALSE
5088 except pexpect.EOF:
5089 main.log.error( self.name + ": EOF exception found" )
5090 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005091 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005092 except Exception:
5093 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005094 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005095
5096 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005097 '''
GlennRC20fc6522015-12-23 23:26:57 -08005098 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005099 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005100 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005101 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005102 Returns:
5103 Returns main.FALSE if an exception is thrown or an error is present
5104 in the response. Otherwise, returns main.TRUE.
5105 NOTE:
5106 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005107 '''
GlennRC20fc6522015-12-23 23:26:57 -08005108 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005109 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005110 deviceStr = device
5111 device = []
5112 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005113
5114 for d in device:
5115 time.sleep( 1 )
5116 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005117 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005118 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005119 if "Error" in response:
5120 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5121 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005122 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005123 except AssertionError:
5124 main.log.exception( "" )
5125 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005126 except TypeError:
5127 main.log.exception( self.name + ": Object not as expected" )
5128 return main.FALSE
5129 except pexpect.EOF:
5130 main.log.error( self.name + ": EOF exception found" )
5131 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005132 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005133 except Exception:
5134 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005135 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005136
5137 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005138 '''
GlennRC20fc6522015-12-23 23:26:57 -08005139 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005140 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005141 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005142 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005143 Returns:
5144 Returns main.FALSE if an exception is thrown or an error is present
5145 in the response. Otherwise, returns main.TRUE.
5146 NOTE:
5147 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005148 '''
GlennRC20fc6522015-12-23 23:26:57 -08005149 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005150 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005151 host = list( host )
5152
5153 for h in host:
5154 time.sleep( 1 )
5155 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005156 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005157 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005158 if "Error" in response:
5159 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5160 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005161 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005162 except AssertionError:
5163 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005164 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005165 except TypeError:
5166 main.log.exception( self.name + ": Object not as expected" )
5167 return main.FALSE
5168 except pexpect.EOF:
5169 main.log.error( self.name + ": EOF exception found" )
5170 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005171 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005172 except Exception:
5173 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005174 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005175
YPZhangfebf7302016-05-24 16:45:56 -07005176 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005177 '''
GlennRCed771242016-01-13 17:02:47 -08005178 Description:
5179 Bring link down or up in the null-provider.
5180 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005181 begin - (string) One end of a device or switch.
5182 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005183 returns:
5184 main.TRUE if no exceptions were thrown and no Errors are
5185 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005186 '''
GlennRCed771242016-01-13 17:02:47 -08005187 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005188 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005189 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005190 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005191 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005192 if "Error" in response or "Failure" in response:
5193 main.log.error( response )
5194 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005195 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005196 except AssertionError:
5197 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005198 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005199 except TypeError:
5200 main.log.exception( self.name + ": Object not as expected" )
5201 return main.FALSE
5202 except pexpect.EOF:
5203 main.log.error( self.name + ": EOF exception found" )
5204 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005205 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005206 except Exception:
5207 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005208 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005209
Jon Hall2c8959e2016-12-16 12:17:34 -08005210 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005211 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005212 Description:
5213 Changes the state of port in an OF switch by means of the
5214 PORTSTATUS OF messages.
5215 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005216 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5217 port - (string) target port in the device. Ex: '2'
5218 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005219 returns:
5220 main.TRUE if no exceptions were thrown and no Errors are
5221 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005222 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005223 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005224 state = state.lower()
5225 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005226 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005227 response = self.sendline( cmd, showResponse=True )
5228 assert response is not None, "Error in sendline"
5229 assert "Command not found:" not in response, response
5230 if "Error" in response or "Failure" in response:
5231 main.log.error( response )
5232 return main.FALSE
5233 return main.TRUE
5234 except AssertionError:
5235 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005236 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005237 except TypeError:
5238 main.log.exception( self.name + ": Object not as expected" )
5239 return main.FALSE
5240 except pexpect.EOF:
5241 main.log.error( self.name + ": EOF exception found" )
5242 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005243 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005244 except Exception:
5245 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005246 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005247
5248 def logSet( self, level="INFO", app="org.onosproject" ):
5249 """
5250 Set the logging level to lvl for a specific app
5251 returns main.TRUE on success
5252 returns main.FALSE if Error occurred
5253 if noExit is True, TestON will not exit, but clean up
5254 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5255 Level defaults to INFO
5256 """
5257 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005258 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -08005259 self.handle.expect( self.karafPrompt )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005260
5261 response = self.handle.before
5262 if re.search( "Error", response ):
5263 return main.FALSE
5264 return main.TRUE
5265 except pexpect.TIMEOUT:
5266 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005267 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005268 except pexpect.EOF:
5269 main.log.error( self.name + ": EOF exception found" )
5270 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005271 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005272 except Exception:
5273 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005274 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005275
5276 def getGraphDict( self, timeout=60, includeHost=False ):
5277 """
5278 Return a dictionary which describes the latest network topology data as a
5279 graph.
5280 An example of the dictionary:
5281 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5282 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5283 Each vertex should at least have an 'edges' attribute which describes the
5284 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005285 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005286 list of attributes.
5287 An example of the edges dictionary:
5288 'edges': { vertex2: { 'port': ..., 'weight': ... },
5289 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005290 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005291 in topology data.
5292 """
5293 graphDict = {}
5294 try:
5295 links = self.links()
5296 links = json.loads( links )
5297 devices = self.devices()
5298 devices = json.loads( devices )
5299 idToDevice = {}
5300 for device in devices:
5301 idToDevice[ device[ 'id' ] ] = device
5302 if includeHost:
5303 hosts = self.hosts()
5304 # FIXME: support 'includeHost' argument
5305 for link in links:
5306 nodeA = link[ 'src' ][ 'device' ]
5307 nodeB = link[ 'dst' ][ 'device' ]
5308 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005309 if nodeA not in graphDict.keys():
5310 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005311 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005312 'type': idToDevice[ nodeA ][ 'type' ],
5313 'available': idToDevice[ nodeA ][ 'available' ],
5314 'role': idToDevice[ nodeA ][ 'role' ],
5315 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5316 'hw': idToDevice[ nodeA ][ 'hw' ],
5317 'sw': idToDevice[ nodeA ][ 'sw' ],
5318 'serial': idToDevice[ nodeA ][ 'serial' ],
5319 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005320 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005321 else:
5322 # Assert nodeB is not connected to any current links of nodeA
5323 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005324 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5325 'type': link[ 'type' ],
5326 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005327 return graphDict
5328 except ( TypeError, ValueError ):
5329 main.log.exception( self.name + ": Object not as expected" )
5330 return None
5331 except KeyError:
5332 main.log.exception( self.name + ": KeyError exception found" )
5333 return None
5334 except AssertionError:
5335 main.log.exception( self.name + ": AssertionError exception found" )
5336 return None
5337 except pexpect.EOF:
5338 main.log.error( self.name + ": EOF exception found" )
5339 main.log.error( self.name + ": " + self.handle.before )
5340 return None
5341 except Exception:
5342 main.log.exception( self.name + ": Uncaught exception!" )
5343 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005344
5345 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005346 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005347 Send command to check intent-perf summary
5348 Returns: dictionary for intent-perf summary
5349 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005350 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005351 cmd = "intent-perf -s"
5352 respDic = {}
5353 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005354 assert resp is not None, "Error in sendline"
5355 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005356 try:
5357 # Generate the dictionary to return
5358 for l in resp.split( "\n" ):
5359 # Delete any white space in line
5360 temp = re.sub( r'\s+', '', l )
5361 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005362 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005363
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005364 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005365 main.log.exception( self.name + ": Object not as expected" )
5366 return None
5367 except KeyError:
5368 main.log.exception( self.name + ": KeyError exception found" )
5369 return None
5370 except AssertionError:
5371 main.log.exception( self.name + ": AssertionError exception found" )
5372 return None
5373 except pexpect.EOF:
5374 main.log.error( self.name + ": EOF exception found" )
5375 main.log.error( self.name + ": " + self.handle.before )
5376 return None
5377 except Exception:
5378 main.log.exception( self.name + ": Uncaught exception!" )
5379 return None
5380 return respDic
5381
Chiyu Chengec63bde2016-11-17 18:11:36 -08005382 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005383 """
5384 Searches the latest ONOS log file for the given search term and
5385 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005386
chengchiyu08303a02016-09-08 17:40:26 -07005387 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005388 searchTerm:
5389 The string to grep from the ONOS log.
5390 startLine:
5391 The term that decides which line is the start to search the searchTerm in
5392 the karaf log. For now, startTerm only works in 'first' mode.
5393 logNum:
5394 In some extreme cases, one karaf log is not big enough to contain all the
5395 information.Because of this, search mutiply logs is necessary to capture
5396 the right result. logNum is the number of karaf logs that we need to search
5397 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005398 mode:
5399 all: return all the strings that contain the search term
5400 last: return the last string that contains the search term
5401 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005402 num: return the number of times that the searchTerm appears in the log
5403 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005404 """
5405 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005406 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005407 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005408 logPath = '/opt/onos/log/karaf.log.'
5409 logPaths = '/opt/onos/log/karaf.log'
5410 for i in range( 1, logNum ):
5411 logPaths = logPath + str( i ) + " " + logPaths
5412 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005413 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005414 # 100000000 is just a extreme large number to make sure this function can
5415 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005416 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005417 if mode == 'all':
5418 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005419 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005420 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005421 elif mode == 'first':
5422 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5423 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005424 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005425 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005426 return num
You Wang6d301d42017-04-21 10:49:33 -07005427 elif mode == 'total':
Jon Halld5a94fb2018-11-13 14:32:23 -08005428 totalLines = self.lineCount( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005429 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005430 else:
5431 main.log.error( self.name + " unsupported mode" )
5432 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005433 before = self.sendline( cmd )
5434 before = before.splitlines()
5435 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005436 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005437 return returnLines
5438 except AssertionError:
5439 main.log.error( self.name + " searchTerm is not string type" )
5440 return None
5441 except pexpect.EOF:
5442 main.log.error( self.name + ": EOF exception found" )
5443 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005444 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005445 except pexpect.TIMEOUT:
5446 main.log.error( self.name + ": TIMEOUT exception found" )
5447 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005448 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005449 except Exception:
5450 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005451 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005452
5453 def vplsShow( self, jsonFormat=True ):
5454 """
5455 Description: Returns result of onos:vpls show, which should list the
5456 configured VPLS networks and the assigned interfaces.
5457 Optional:
5458 * jsonFormat: enable json formatting of output
5459 Returns:
5460 The output of the command or None on error.
5461 """
5462 try:
5463 cmdStr = "vpls show"
5464 if jsonFormat:
5465 raise NotImplementedError
5466 cmdStr += " -j"
5467 handle = self.sendline( cmdStr )
5468 assert handle is not None, "Error in sendline"
5469 assert "Command not found:" not in handle, handle
5470 return handle
5471 except AssertionError:
5472 main.log.exception( "" )
5473 return None
5474 except TypeError:
5475 main.log.exception( self.name + ": Object not as expected" )
5476 return None
5477 except pexpect.EOF:
5478 main.log.error( self.name + ": EOF exception found" )
5479 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005480 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005481 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005482 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005483 return None
5484 except Exception:
5485 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005486 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005487
5488 def parseVplsShow( self ):
5489 """
5490 Parse the cli output of 'vpls show' into json output. This is required
5491 as there is currently no json output available.
5492 """
5493 try:
5494 output = []
5495 raw = self.vplsShow( jsonFormat=False )
5496 namePat = "VPLS name: (?P<name>\w+)"
5497 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5498 encapPat = "Encapsulation: (?P<encap>\w+)"
5499 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5500 mIter = re.finditer( pattern, raw )
5501 for match in mIter:
5502 item = {}
5503 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005504 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005505 if ifaces == [ "" ]:
5506 ifaces = []
5507 item[ 'interfaces' ] = ifaces
5508 encap = match.group( 'encap' )
5509 if encap != 'NONE':
5510 item[ 'encapsulation' ] = encap.lower()
5511 output.append( item )
5512 return output
5513 except Exception:
5514 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005515 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005516
5517 def vplsList( self, jsonFormat=True ):
5518 """
5519 Description: Returns result of onos:vpls list, which should list the
5520 configured VPLS networks.
5521 Optional:
5522 * jsonFormat: enable json formatting of output
5523 """
5524 try:
5525 cmdStr = "vpls list"
5526 if jsonFormat:
5527 raise NotImplementedError
5528 cmdStr += " -j"
5529 handle = self.sendline( cmdStr )
5530 assert handle is not None, "Error in sendline"
5531 assert "Command not found:" not in handle, handle
5532 return handle
5533 except AssertionError:
5534 main.log.exception( "" )
5535 return None
5536 except TypeError:
5537 main.log.exception( self.name + ": Object not as expected" )
5538 return None
5539 except pexpect.EOF:
5540 main.log.error( self.name + ": EOF exception found" )
5541 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005542 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005543 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005544 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005545 return None
5546 except Exception:
5547 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005548 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005549
5550 def vplsCreate( self, network ):
5551 """
5552 CLI command to create a new VPLS network.
5553 Required arguments:
5554 network - String name of the network to create.
5555 returns:
5556 main.TRUE on success and main.FALSE on failure
5557 """
5558 try:
5559 network = str( network )
5560 cmdStr = "vpls create "
5561 cmdStr += network
5562 output = self.sendline( cmdStr )
5563 assert output is not None, "Error in sendline"
5564 assert "Command not found:" not in output, output
5565 assert "Error executing command" not in output, output
5566 assert "VPLS already exists:" not in output, output
5567 return main.TRUE
5568 except AssertionError:
5569 main.log.exception( "" )
5570 return main.FALSE
5571 except TypeError:
5572 main.log.exception( self.name + ": Object not as expected" )
5573 return main.FALSE
5574 except pexpect.EOF:
5575 main.log.error( self.name + ": EOF exception found" )
5576 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005577 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005578 except Exception:
5579 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005580 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005581
5582 def vplsDelete( self, network ):
5583 """
5584 CLI command to delete a VPLS network.
5585 Required arguments:
5586 network - Name of the network to delete.
5587 returns:
5588 main.TRUE on success and main.FALSE on failure
5589 """
5590 try:
5591 network = str( network )
5592 cmdStr = "vpls delete "
5593 cmdStr += network
5594 output = self.sendline( cmdStr )
5595 assert output is not None, "Error in sendline"
5596 assert "Command not found:" not in output, output
5597 assert "Error executing command" not in output, output
5598 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005599 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005600 return main.TRUE
5601 except AssertionError:
5602 main.log.exception( "" )
5603 return main.FALSE
5604 except TypeError:
5605 main.log.exception( self.name + ": Object not as expected" )
5606 return main.FALSE
5607 except pexpect.EOF:
5608 main.log.error( self.name + ": EOF exception found" )
5609 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005610 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005611 except Exception:
5612 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005613 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005614
5615 def vplsAddIface( self, network, iface ):
5616 """
5617 CLI command to add an interface to a VPLS network.
5618 Required arguments:
5619 network - Name of the network to add the interface to.
5620 iface - The ONOS name for an interface.
5621 returns:
5622 main.TRUE on success and main.FALSE on failure
5623 """
5624 try:
5625 network = str( network )
5626 iface = str( iface )
5627 cmdStr = "vpls add-if "
5628 cmdStr += network + " " + iface
5629 output = self.sendline( cmdStr )
5630 assert output is not None, "Error in sendline"
5631 assert "Command not found:" not in output, output
5632 assert "Error executing command" not in output, output
5633 assert "already associated to network" not in output, output
5634 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005635 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005636 return main.TRUE
5637 except AssertionError:
5638 main.log.exception( "" )
5639 return main.FALSE
5640 except TypeError:
5641 main.log.exception( self.name + ": Object not as expected" )
5642 return main.FALSE
5643 except pexpect.EOF:
5644 main.log.error( self.name + ": EOF exception found" )
5645 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005646 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005647 except Exception:
5648 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005649 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005650
5651 def vplsRemIface( self, network, iface ):
5652 """
5653 CLI command to remove an interface from a VPLS network.
5654 Required arguments:
5655 network - Name of the network to remove the interface from.
5656 iface - Name of the interface to remove.
5657 returns:
5658 main.TRUE on success and main.FALSE on failure
5659 """
5660 try:
5661 iface = str( iface )
5662 cmdStr = "vpls rem-if "
5663 cmdStr += network + " " + iface
5664 output = self.sendline( cmdStr )
5665 assert output is not None, "Error in sendline"
5666 assert "Command not found:" not in output, output
5667 assert "Error executing command" not in output, output
5668 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005669 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005670 return main.TRUE
5671 except AssertionError:
5672 main.log.exception( "" )
5673 return main.FALSE
5674 except TypeError:
5675 main.log.exception( self.name + ": Object not as expected" )
5676 return main.FALSE
5677 except pexpect.EOF:
5678 main.log.error( self.name + ": EOF exception found" )
5679 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005680 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005681 except Exception:
5682 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005683 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005684
5685 def vplsClean( self ):
5686 """
5687 Description: Clears the VPLS app configuration.
5688 Returns: main.TRUE on success and main.FALSE on failure
5689 """
5690 try:
5691 cmdStr = "vpls clean"
5692 handle = self.sendline( cmdStr )
5693 assert handle is not None, "Error in sendline"
5694 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005695 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005696 return handle
5697 except AssertionError:
5698 main.log.exception( "" )
5699 return main.FALSE
5700 except TypeError:
5701 main.log.exception( self.name + ": Object not as expected" )
5702 return main.FALSE
5703 except pexpect.EOF:
5704 main.log.error( self.name + ": EOF exception found" )
5705 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005706 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005707 except Exception:
5708 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005709 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005710
5711 def vplsSetEncap( self, network, encapType ):
5712 """
5713 CLI command to add an interface to a VPLS network.
5714 Required arguments:
5715 network - Name of the network to create.
5716 encapType - Type of encapsulation.
5717 returns:
5718 main.TRUE on success and main.FALSE on failure
5719 """
5720 try:
5721 network = str( network )
5722 encapType = str( encapType ).upper()
5723 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5724 cmdStr = "vpls set-encap "
5725 cmdStr += network + " " + encapType
5726 output = self.sendline( cmdStr )
5727 assert output is not None, "Error in sendline"
5728 assert "Command not found:" not in output, output
5729 assert "Error executing command" not in output, output
5730 assert "already associated to network" not in output, output
5731 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005732 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005733 return main.TRUE
5734 except AssertionError:
5735 main.log.exception( "" )
5736 return main.FALSE
5737 except TypeError:
5738 main.log.exception( self.name + ": Object not as expected" )
5739 return main.FALSE
5740 except pexpect.EOF:
5741 main.log.error( self.name + ": EOF exception found" )
5742 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005743 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005744 except Exception:
5745 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005746 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005747
5748 def interfaces( self, jsonFormat=True ):
5749 """
5750 Description: Returns result of interfaces command.
5751 Optional:
5752 * jsonFormat: enable json formatting of output
5753 Returns:
5754 The output of the command or None on error.
5755 """
5756 try:
5757 cmdStr = "interfaces"
5758 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005759 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005760 cmdStr += " -j"
5761 handle = self.sendline( cmdStr )
5762 assert handle is not None, "Error in sendline"
5763 assert "Command not found:" not in handle, handle
5764 return handle
5765 except AssertionError:
5766 main.log.exception( "" )
5767 return None
5768 except TypeError:
5769 main.log.exception( self.name + ": Object not as expected" )
5770 return None
5771 except pexpect.EOF:
5772 main.log.error( self.name + ": EOF exception found" )
5773 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005774 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005775 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005776 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005777 return None
5778 except Exception:
5779 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005780 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005781
5782 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005783 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005784 Get the timestamp of searchTerm from karaf log.
5785
5786 Arguments:
5787 splitTerm_before and splitTerm_after:
5788
5789 The terms that split the string that contains the timeStamp of
5790 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5791 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5792 and the splitTerm_after is "x"
5793
5794 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005795 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005796 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005797 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005798 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005799 return main.ERROR
5800 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005801 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005802 main.log.warn( "Captured timestamp string is empty" )
5803 return main.ERROR
5804 lines = lines[ 0 ]
5805 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005806 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005807 # get the target value
5808 line = lines.split( splitTerm_before )
5809 key = line[ 1 ].split( splitTerm_after )
5810 return int( key[ 0 ] )
5811 except IndexError:
5812 main.log.warn( "Index Error!" )
5813 return main.ERROR
5814 except AssertionError:
5815 main.log.warn( "Search Term Not Found " )
5816 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005817
5818 def workQueueAdd( self, queueName, value ):
5819 """
5820 CLI command to add a string to the specified Work Queue.
5821 This function uses the distributed primitives test app, which
5822 gives some cli access to distributed primitives for testing
5823 purposes only.
5824
5825 Required arguments:
5826 queueName - The name of the queue to add to
5827 value - The value to add to the queue
5828 returns:
5829 main.TRUE on success, main.FALSE on failure and
5830 main.ERROR on error.
5831 """
5832 try:
5833 queueName = str( queueName )
5834 value = str( value )
5835 prefix = "work-queue-test"
5836 operation = "add"
5837 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5838 output = self.distPrimitivesSend( cmdStr )
5839 if "Invalid operation name" in output:
5840 main.log.warn( output )
5841 return main.ERROR
5842 elif "Done" in output:
5843 return main.TRUE
5844 except TypeError:
5845 main.log.exception( self.name + ": Object not as expected" )
5846 return main.ERROR
5847 except Exception:
5848 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005849 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005850
5851 def workQueueAddMultiple( self, queueName, value1, value2 ):
5852 """
5853 CLI command to add two strings to the specified Work Queue.
5854 This function uses the distributed primitives test app, which
5855 gives some cli access to distributed primitives for testing
5856 purposes only.
5857
5858 Required arguments:
5859 queueName - The name of the queue to add to
5860 value1 - The first value to add to the queue
5861 value2 - The second value to add to the queue
5862 returns:
5863 main.TRUE on success, main.FALSE on failure and
5864 main.ERROR on error.
5865 """
5866 try:
5867 queueName = str( queueName )
5868 value1 = str( value1 )
5869 value2 = str( value2 )
5870 prefix = "work-queue-test"
5871 operation = "addMultiple"
5872 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5873 output = self.distPrimitivesSend( cmdStr )
5874 if "Invalid operation name" in output:
5875 main.log.warn( output )
5876 return main.ERROR
5877 elif "Done" in output:
5878 return main.TRUE
5879 except TypeError:
5880 main.log.exception( self.name + ": Object not as expected" )
5881 return main.ERROR
5882 except Exception:
5883 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005884 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005885
5886 def workQueueTakeAndComplete( self, queueName, number=1 ):
5887 """
5888 CLI command to take a value from the specified Work Queue and compelte it.
5889 This function uses the distributed primitives test app, which
5890 gives some cli access to distributed primitives for testing
5891 purposes only.
5892
5893 Required arguments:
5894 queueName - The name of the queue to add to
5895 number - The number of items to take and complete
5896 returns:
5897 main.TRUE on success, main.FALSE on failure and
5898 main.ERROR on error.
5899 """
5900 try:
5901 queueName = str( queueName )
5902 number = str( int( number ) )
5903 prefix = "work-queue-test"
5904 operation = "takeAndComplete"
5905 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5906 output = self.distPrimitivesSend( cmdStr )
5907 if "Invalid operation name" in output:
5908 main.log.warn( output )
5909 return main.ERROR
5910 elif "Done" in output:
5911 return main.TRUE
5912 except TypeError:
5913 main.log.exception( self.name + ": Object not as expected" )
5914 return main.ERROR
5915 except Exception:
5916 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005917 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005918
5919 def workQueueDestroy( self, queueName ):
5920 """
5921 CLI command to destroy the specified Work Queue.
5922 This function uses the distributed primitives test app, which
5923 gives some cli access to distributed primitives for testing
5924 purposes only.
5925
5926 Required arguments:
5927 queueName - The name of the queue to add to
5928 returns:
5929 main.TRUE on success, main.FALSE on failure and
5930 main.ERROR on error.
5931 """
5932 try:
5933 queueName = str( queueName )
5934 prefix = "work-queue-test"
5935 operation = "destroy"
5936 cmdStr = " ".join( [ prefix, queueName, operation ] )
5937 output = self.distPrimitivesSend( cmdStr )
5938 if "Invalid operation name" in output:
5939 main.log.warn( output )
5940 return main.ERROR
5941 return main.TRUE
5942 except TypeError:
5943 main.log.exception( self.name + ": Object not as expected" )
5944 return main.ERROR
5945 except Exception:
5946 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005947 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005948
5949 def workQueueTotalPending( self, queueName ):
5950 """
5951 CLI command to get the Total Pending items of the specified Work Queue.
5952 This function uses the distributed primitives test app, which
5953 gives some cli access to distributed primitives for testing
5954 purposes only.
5955
5956 Required arguments:
5957 queueName - The name of the queue to add to
5958 returns:
5959 The number of Pending items in the specified work queue or
5960 None on error
5961 """
5962 try:
5963 queueName = str( queueName )
5964 prefix = "work-queue-test"
5965 operation = "totalPending"
5966 cmdStr = " ".join( [ prefix, queueName, operation ] )
5967 output = self.distPrimitivesSend( cmdStr )
5968 pattern = r'\d+'
5969 if "Invalid operation name" in output:
5970 main.log.warn( output )
5971 return None
5972 else:
5973 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005974 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005975 except ( AttributeError, TypeError ):
5976 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5977 return None
5978 except Exception:
5979 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005980 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005981
5982 def workQueueTotalCompleted( self, queueName ):
5983 """
5984 CLI command to get the Total Completed items of the specified Work Queue.
5985 This function uses the distributed primitives test app, which
5986 gives some cli access to distributed primitives for testing
5987 purposes only.
5988
5989 Required arguments:
5990 queueName - The name of the queue to add to
5991 returns:
5992 The number of complete items in the specified work queue or
5993 None on error
5994 """
5995 try:
5996 queueName = str( queueName )
5997 prefix = "work-queue-test"
5998 operation = "totalCompleted"
5999 cmdStr = " ".join( [ prefix, queueName, operation ] )
6000 output = self.distPrimitivesSend( cmdStr )
6001 pattern = r'\d+'
6002 if "Invalid operation name" in output:
6003 main.log.warn( output )
6004 return None
6005 else:
6006 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006007 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006008 except ( AttributeError, TypeError ):
6009 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6010 return None
6011 except Exception:
6012 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006013 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006014
6015 def workQueueTotalInProgress( self, queueName ):
6016 """
6017 CLI command to get the Total In Progress items of the specified Work Queue.
6018 This function uses the distributed primitives test app, which
6019 gives some cli access to distributed primitives for testing
6020 purposes only.
6021
6022 Required arguments:
6023 queueName - The name of the queue to add to
6024 returns:
6025 The number of In Progress items in the specified work queue or
6026 None on error
6027 """
6028 try:
6029 queueName = str( queueName )
6030 prefix = "work-queue-test"
6031 operation = "totalInProgress"
6032 cmdStr = " ".join( [ prefix, queueName, operation ] )
6033 output = self.distPrimitivesSend( cmdStr )
6034 pattern = r'\d+'
6035 if "Invalid operation name" in output:
6036 main.log.warn( output )
6037 return None
6038 else:
6039 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006040 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006041 except ( AttributeError, TypeError ):
6042 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6043 return None
6044 except Exception:
6045 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006046 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00006047
6048 def events( self, args='-a' ):
6049 """
6050 Description: Returns events -a command output
6051 Optional:
6052 add other arguments
6053 """
6054 try:
6055 cmdStr = "events"
6056 if args:
6057 cmdStr += " " + args
6058 handle = self.sendline( cmdStr )
6059 assert handle is not None, "Error in sendline"
6060 assert "Command not found:" not in handle, handle
6061 return handle
6062 except AssertionError:
6063 main.log.exception( "" )
6064 return None
6065 except TypeError:
6066 main.log.exception( self.name + ": Object not as expected" )
6067 return None
6068 except pexpect.EOF:
6069 main.log.error( self.name + ": EOF exception found" )
6070 main.log.error( self.name + ": " + self.handle.before )
6071 main.cleanAndExit()
6072 except Exception:
6073 main.log.exception( self.name + ": Uncaught exception!" )
6074 main.cleanAndExit()
6075
6076 def getMaster( self, deviceID ):
6077 """
6078 Description: Obtains current master using "roles" command for a specific deviceID
6079 """
6080 try:
6081 return str( self.getRole( deviceID )[ 'master' ] )
6082 except AssertionError:
6083 main.log.exception( "" )
6084 return None
6085 except TypeError:
6086 main.log.exception( self.name + ": Object not as expected" )
6087 return None
6088 except pexpect.EOF:
6089 main.log.error( self.name + ": EOF exception found" )
6090 main.log.error( self.name + ": " + self.handle.before )
6091 main.cleanAndExit()
6092 except Exception:
6093 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006094 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006095
6096 def issu( self ):
6097 """
6098 Short summary of In-Service Software Upgrade status
6099
6100 Returns the output of the cli command or None on Error
6101 """
6102 try:
6103 cmdStr = "issu"
6104 handle = self.sendline( cmdStr )
6105 assert handle is not None, "Error in sendline"
6106 assert "Command not found:" not in handle, handle
6107 assert "Unsupported command:" not in handle, handle
6108 return handle
6109 except AssertionError:
6110 main.log.exception( "" )
6111 return None
6112 except TypeError:
6113 main.log.exception( self.name + ": Object not as expected" )
6114 return None
6115 except pexpect.EOF:
6116 main.log.error( self.name + ": EOF exception found" )
6117 main.log.error( self.name + ": " + self.handle.before )
6118 main.cleanAndExit()
6119 except Exception:
6120 main.log.exception( self.name + ": Uncaught exception!" )
6121 main.cleanAndExit()
6122
6123 def issuInit( self ):
6124 """
6125 Initiates an In-Service Software Upgrade
6126
6127 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6128 """
6129 try:
6130 cmdStr = "issu init"
6131 handle = self.sendline( cmdStr )
6132 assert handle is not None, "Error in sendline"
6133 assert "Command not found:" not in handle, handle
6134 assert "Unsupported command:" not in handle, handle
6135 if "Initialized" in handle:
6136 return main.TRUE
6137 else:
6138 return main.FALSE
6139 except AssertionError:
6140 main.log.exception( "" )
6141 return main.ERROR
6142 except TypeError:
6143 main.log.exception( self.name + ": Object not as expected" )
6144 return main.ERROR
6145 except pexpect.EOF:
6146 main.log.error( self.name + ": EOF exception found" )
6147 main.log.error( self.name + ": " + self.handle.before )
6148 main.cleanAndExit()
6149 except Exception:
6150 main.log.exception( self.name + ": Uncaught exception!" )
6151 main.cleanAndExit()
6152
6153 def issuUpgrade( self ):
6154 """
6155 Transitions stores to upgraded nodes
6156
6157 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6158 """
6159 try:
6160 cmdStr = "issu upgrade"
6161 handle = self.sendline( cmdStr )
6162 assert handle is not None, "Error in sendline"
6163 assert "Command not found:" not in handle, handle
6164 assert "Unsupported command:" not in handle, handle
6165 if "Upgraded" in handle:
6166 return main.TRUE
6167 else:
6168 return main.FALSE
6169 except AssertionError:
6170 main.log.exception( "" )
6171 return main.ERROR
6172 except TypeError:
6173 main.log.exception( self.name + ": Object not as expected" )
6174 return main.ERROR
6175 except pexpect.EOF:
6176 main.log.error( self.name + ": EOF exception found" )
6177 main.log.error( self.name + ": " + self.handle.before )
6178 main.cleanAndExit()
6179 except Exception:
6180 main.log.exception( self.name + ": Uncaught exception!" )
6181 main.cleanAndExit()
6182
6183 def issuCommit( self ):
6184 """
6185 Finalizes an In-Service Software Upgrade
6186
6187 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6188 """
6189 try:
6190 cmdStr = "issu commit"
6191 handle = self.sendline( cmdStr )
6192 assert handle is not None, "Error in sendline"
6193 assert "Command not found:" not in handle, handle
6194 assert "Unsupported command:" not in handle, handle
6195 # TODO: Check the version returned by this command
6196 if "Committed version" in handle:
6197 return main.TRUE
6198 else:
6199 return main.FALSE
6200 except AssertionError:
6201 main.log.exception( "" )
6202 return main.ERROR
6203 except TypeError:
6204 main.log.exception( self.name + ": Object not as expected" )
6205 return main.ERROR
6206 except pexpect.EOF:
6207 main.log.error( self.name + ": EOF exception found" )
6208 main.log.error( self.name + ": " + self.handle.before )
6209 main.cleanAndExit()
6210 except Exception:
6211 main.log.exception( self.name + ": Uncaught exception!" )
6212 main.cleanAndExit()
6213
6214 def issuRollback( self ):
6215 """
6216 Rolls back an In-Service Software Upgrade
6217
6218 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6219 """
6220 try:
6221 cmdStr = "issu rollback"
6222 handle = self.sendline( cmdStr )
6223 assert handle is not None, "Error in sendline"
6224 assert "Command not found:" not in handle, handle
6225 assert "Unsupported command:" not in handle, handle
6226 # TODO: Check the version returned by this command
6227 if "Rolled back to version" in handle:
6228 return main.TRUE
6229 else:
6230 return main.FALSE
6231 except AssertionError:
6232 main.log.exception( "" )
6233 return main.ERROR
6234 except TypeError:
6235 main.log.exception( self.name + ": Object not as expected" )
6236 return main.ERROR
6237 except pexpect.EOF:
6238 main.log.error( self.name + ": EOF exception found" )
6239 main.log.error( self.name + ": " + self.handle.before )
6240 main.cleanAndExit()
6241 except Exception:
6242 main.log.exception( self.name + ": Uncaught exception!" )
6243 main.cleanAndExit()
6244
6245 def issuReset( self ):
6246 """
6247 Resets the In-Service Software Upgrade status after a rollback
6248
6249 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6250 """
6251 try:
6252 cmdStr = "issu reset"
6253 handle = self.sendline( cmdStr )
6254 assert handle is not None, "Error in sendline"
6255 assert "Command not found:" not in handle, handle
6256 assert "Unsupported command:" not in handle, handle
6257 # TODO: Check the version returned by this command
6258 if "Reset version" in handle:
6259 return main.TRUE
6260 else:
6261 return main.FALSE
6262 except AssertionError:
6263 main.log.exception( "" )
6264 return main.ERROR
6265 except TypeError:
6266 main.log.exception( self.name + ": Object not as expected" )
6267 return main.ERROR
6268 except pexpect.EOF:
6269 main.log.error( self.name + ": EOF exception found" )
6270 main.log.error( self.name + ": " + self.handle.before )
6271 main.cleanAndExit()
6272 except Exception:
6273 main.log.exception( self.name + ": Uncaught exception!" )
6274 main.cleanAndExit()
6275
6276 def issuStatus( self ):
6277 """
6278 Status of an In-Service Software Upgrade
6279
6280 Returns the output of the cli command or None on Error
6281 """
6282 try:
6283 cmdStr = "issu status"
6284 handle = self.sendline( cmdStr )
6285 assert handle is not None, "Error in sendline"
6286 assert "Command not found:" not in handle, handle
6287 assert "Unsupported command:" not in handle, handle
6288 return handle
6289 except AssertionError:
6290 main.log.exception( "" )
6291 return None
6292 except TypeError:
6293 main.log.exception( self.name + ": Object not as expected" )
6294 return None
6295 except pexpect.EOF:
6296 main.log.error( self.name + ": EOF exception found" )
6297 main.log.error( self.name + ": " + self.handle.before )
6298 main.cleanAndExit()
6299 except Exception:
6300 main.log.exception( self.name + ": Uncaught exception!" )
6301 main.cleanAndExit()
6302
6303 def issuVersion( self ):
6304 """
6305 Get the version of an In-Service Software Upgrade
6306
6307 Returns the output of the cli command or None on Error
6308 """
6309 try:
6310 cmdStr = "issu version"
6311 handle = self.sendline( cmdStr )
6312 assert handle is not None, "Error in sendline"
6313 assert "Command not found:" not in handle, handle
6314 assert "Unsupported command:" not in handle, handle
6315 return handle
6316 except AssertionError:
6317 main.log.exception( "" )
6318 return None
6319 except TypeError:
6320 main.log.exception( self.name + ": Object not as expected" )
6321 return None
6322 except pexpect.EOF:
6323 main.log.error( self.name + ": EOF exception found" )
6324 main.log.error( self.name + ": " + self.handle.before )
6325 main.cleanAndExit()
6326 except Exception:
6327 main.log.exception( self.name + ": Uncaught exception!" )
6328 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006329
6330 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6331 """
6332 Create a multicast route by calling 'mcast-join' command
6333 sIP: source IP of the multicast route
6334 groupIP: group IP of the multicast route
6335 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6336 dPorts: a list of destination ports of the multicast route
6337 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6338 """
6339 try:
6340 cmdStr = "mcast-join"
6341 cmdStr += " " + str( sIP )
6342 cmdStr += " " + str( groupIP )
6343 cmdStr += " " + str( sPort )
6344 assert isinstance( dPorts, list )
6345 for dPort in dPorts:
6346 cmdStr += " " + str( dPort )
6347 handle = self.sendline( cmdStr )
6348 assert handle is not None, "Error in sendline"
6349 assert "Command not found:" not in handle, handle
6350 assert "Unsupported command:" not in handle, handle
6351 assert "Error executing command" not in handle, handle
6352 if "Added the mcast route" in handle:
6353 return main.TRUE
6354 else:
6355 return main.FALSE
6356 except AssertionError:
6357 main.log.exception( "" )
6358 return None
6359 except TypeError:
6360 main.log.exception( self.name + ": Object not as expected" )
6361 return None
6362 except pexpect.EOF:
6363 main.log.error( self.name + ": EOF exception found" )
6364 main.log.error( self.name + ": " + self.handle.before )
6365 main.cleanAndExit()
6366 except Exception:
6367 main.log.exception( self.name + ": Uncaught exception!" )
6368 main.cleanAndExit()
6369
6370 def mcastDelete( self, sIP, groupIP, dPorts ):
6371 """
6372 Delete a multicast route by calling 'mcast-delete' command
6373 sIP: source IP of the multicast route
6374 groupIP: group IP of the multicast route
6375 dPorts: a list of destination ports of the multicast route
6376 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6377 """
6378 try:
6379 cmdStr = "mcast-delete"
6380 cmdStr += " " + str( sIP )
6381 cmdStr += " " + str( groupIP )
6382 assert isinstance( dPorts, list )
6383 for dPort in dPorts:
6384 cmdStr += " " + str( dPort )
6385 handle = self.sendline( cmdStr )
6386 assert handle is not None, "Error in sendline"
6387 assert "Command not found:" not in handle, handle
6388 assert "Unsupported command:" not in handle, handle
6389 assert "Error executing command" not in handle, handle
6390 if "Updated the mcast route" in handle:
6391 return main.TRUE
6392 else:
6393 return main.FALSE
6394 except AssertionError:
6395 main.log.exception( "" )
6396 return None
6397 except TypeError:
6398 main.log.exception( self.name + ": Object not as expected" )
6399 return None
6400 except pexpect.EOF:
6401 main.log.error( self.name + ": EOF exception found" )
6402 main.log.error( self.name + ": " + self.handle.before )
6403 main.cleanAndExit()
6404 except Exception:
6405 main.log.exception( self.name + ": Uncaught exception!" )
6406 main.cleanAndExit()
6407
6408 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6409 """
6410 Create a multicast route by calling 'mcast-host-join' command
6411 sAddr: we can provide * for ASM or a specific address for SSM
6412 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006413 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006414 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6415 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6416 """
6417 try:
6418 cmdStr = "mcast-host-join"
6419 cmdStr += " -sAddr " + str( sAddr )
6420 cmdStr += " -gAddr " + str( gAddr )
6421 assert isinstance( srcs, list )
6422 for src in srcs:
6423 cmdStr += " -srcs " + str( src )
6424 assert isinstance( sinks, list )
6425 for sink in sinks:
6426 cmdStr += " -sinks " + str( sink )
6427 handle = self.sendline( cmdStr )
6428 assert handle is not None, "Error in sendline"
6429 assert "Command not found:" not in handle, handle
6430 assert "Unsupported command:" not in handle, handle
6431 assert "Error executing command" not in handle, handle
6432 if "Added the mcast route" in handle:
6433 return main.TRUE
6434 else:
6435 return main.FALSE
6436 except AssertionError:
6437 main.log.exception( "" )
6438 return None
6439 except TypeError:
6440 main.log.exception( self.name + ": Object not as expected" )
6441 return None
6442 except pexpect.EOF:
6443 main.log.error( self.name + ": EOF exception found" )
6444 main.log.error( self.name + ": " + self.handle.before )
6445 main.cleanAndExit()
6446 except Exception:
6447 main.log.exception( self.name + ": Uncaught exception!" )
6448 main.cleanAndExit()
6449
6450 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6451 """
6452 Delete multicast sink(s) by calling 'mcast-host-delete' command
6453 sAddr: we can provide * for ASM or a specific address for SSM
6454 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006455 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006456 will delete the route if not specified
6457 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6458 """
6459 try:
6460 cmdStr = "mcast-host-delete"
6461 cmdStr += " -sAddr " + str( sAddr )
6462 cmdStr += " -gAddr " + str( gAddr )
6463 if host:
6464 cmdStr += " -h " + str( host )
6465 handle = self.sendline( cmdStr )
6466 assert handle is not None, "Error in sendline"
6467 assert "Command not found:" not in handle, handle
6468 assert "Unsupported command:" not in handle, handle
6469 assert "Error executing command" not in handle, handle
6470 if "Updated the mcast route" in handle:
6471 return main.TRUE
6472 elif "Deleted the mcast route" in handle:
6473 return main.TRUE
6474 else:
6475 return main.FALSE
6476 except AssertionError:
6477 main.log.exception( "" )
6478 return None
6479 except TypeError:
6480 main.log.exception( self.name + ": Object not as expected" )
6481 return None
6482 except pexpect.EOF:
6483 main.log.error( self.name + ": EOF exception found" )
6484 main.log.error( self.name + ": " + self.handle.before )
6485 main.cleanAndExit()
6486 except Exception:
6487 main.log.exception( self.name + ": Uncaught exception!" )
6488 main.cleanAndExit()
6489
You Wang547893e2018-05-08 13:34:59 -07006490 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6491 """
6492 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6493 sAddr: we can provide * for ASM or a specific address for SSM
6494 gAddr: specifies multicast group address
6495 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6496 will delete the route if not specified
6497 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6498 """
6499 try:
6500 cmdStr = "mcast-sink-delete"
6501 cmdStr += " -sAddr " + str( sAddr )
6502 cmdStr += " -gAddr " + str( gAddr )
6503 if sink:
6504 cmdStr += " -s " + str( sink )
6505 handle = self.sendline( cmdStr )
6506 assert handle is not None, "Error in sendline"
6507 assert "Command not found:" not in handle, handle
6508 assert "Unsupported command:" not in handle, handle
6509 assert "Error executing command" not in handle, handle
6510 if "Updated the mcast route" in handle:
6511 return main.TRUE
6512 elif "Deleted the mcast route" in handle:
6513 return main.TRUE
6514 else:
6515 return main.FALSE
6516 except AssertionError:
6517 main.log.exception( "" )
6518 return None
6519 except TypeError:
6520 main.log.exception( self.name + ": Object not as expected" )
6521 return None
6522 except pexpect.EOF:
6523 main.log.error( self.name + ": EOF exception found" )
6524 main.log.error( self.name + ": " + self.handle.before )
6525 main.cleanAndExit()
6526 except Exception:
6527 main.log.exception( self.name + ": Uncaught exception!" )
6528 main.cleanAndExit()
6529
You Wange24d6272018-03-27 21:18:50 -07006530 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6531 """
6532 Delete multicast src(s) by calling 'mcast-source-delete' command
6533 sAddr: we can provide * for ASM or a specific address for SSM
6534 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006535 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 -07006536 will delete the route if not specified
6537 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6538 """
6539 try:
6540 cmdStr = "mcast-source-delete"
6541 cmdStr += " -sAddr " + str( sAddr )
6542 cmdStr += " -gAddr " + str( gAddr )
6543 if srcs:
6544 assert isinstance( srcs, list )
6545 for src in srcs:
6546 cmdStr += " -src " + str( src )
6547 handle = self.sendline( cmdStr )
6548 assert handle is not None, "Error in sendline"
6549 assert "Command not found:" not in handle, handle
6550 assert "Unsupported command:" not in handle, handle
6551 assert "Error executing command" not in handle, handle
6552 if "Updated the mcast route" in handle:
6553 return main.TRUE
6554 elif "Deleted the mcast route" in handle:
6555 return main.TRUE
6556 else:
6557 return main.FALSE
6558 except AssertionError:
6559 main.log.exception( "" )
6560 return None
6561 except TypeError:
6562 main.log.exception( self.name + ": Object not as expected" )
6563 return None
6564 except pexpect.EOF:
6565 main.log.error( self.name + ": EOF exception found" )
6566 main.log.error( self.name + ": " + self.handle.before )
6567 main.cleanAndExit()
6568 except Exception:
6569 main.log.exception( self.name + ": Uncaught exception!" )
6570 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006571
6572 def netcfg( self, jsonFormat=True, args="" ):
6573 """
6574 Run netcfg cli command with given args
6575 """
6576 try:
6577 cmdStr = "netcfg"
6578 if jsonFormat:
6579 cmdStr = cmdStr + " -j"
6580 if args:
6581 cmdStr = cmdStr + " " + str( args )
6582 handle = self.sendline( cmdStr )
6583 assert handle is not None, "Error in sendline"
6584 assert "Command not found:" not in handle, handle
6585 assert "Unsupported command:" not in handle, handle
6586 assert "Error executing command" not in handle, handle
6587 return handle
6588 except AssertionError:
6589 main.log.exception( "" )
6590 return None
6591 except TypeError:
6592 main.log.exception( self.name + ": Object not as expected" )
6593 return None
6594 except pexpect.EOF:
6595 main.log.error( self.name + ": EOF exception found" )
6596 main.log.error( self.name + ": " + self.handle.before )
6597 main.cleanAndExit()
6598 except Exception:
6599 main.log.exception( self.name + ": Uncaught exception!" )
6600 main.cleanAndExit()
6601
You Wang0fa76e72018-05-18 11:33:25 -07006602 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006603 """
You Wang54b1d672018-06-11 16:44:13 -07006604 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006605 Options:
6606 sAddr: IP address of the source host
6607 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006608 ipv6: True if hosts are IPv6
6609 verbose: return verbose t3 output if True
6610 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006611 """
6612 try:
6613 # Collect information of both hosts from onos
6614 hosts = self.hosts()
6615 hosts = json.loads( hosts )
6616 sHost = None
6617 dHost = None
6618 for host in hosts:
6619 if sAddr in host[ "ipAddresses" ]:
6620 sHost = host
6621 elif dAddr in host[ "ipAddresses" ]:
6622 dHost = host
6623 if sHost and dHost:
6624 break
6625 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006626 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006627 if simple:
6628 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006629 cmdStr = "t3-troubleshoot-simple"
6630 if verbose:
6631 cmdStr += " -vv"
6632 if ipv6:
6633 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006634 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006635 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006636 else:
You Wang54b1d672018-06-11 16:44:13 -07006637 for location in sHost[ "locations" ]:
6638 cmdStr = "t3-troubleshoot"
6639 if verbose:
6640 cmdStr += " -vv"
6641 if ipv6:
6642 cmdStr += " -et ipv6"
6643 cmdStr += " -s " + str( sAddr )
6644 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6645 cmdStr += " -sm " + str( sHost[ "mac" ] )
6646 if sHost[ "vlan" ] != "None":
6647 cmdStr += " -vid " + sHost[ "vlan" ]
6648 cmdStr += " -d " + str( dAddr )
6649 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6650 netcfg = json.loads( netcfg )
6651 assert netcfg, "Failed to get netcfg"
6652 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6653 cmdList.append( cmdStr )
6654 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006655 except AssertionError:
6656 main.log.exception( "" )
6657 return None
6658 except ( KeyError, TypeError ):
6659 main.log.exception( self.name + ": Object not as expected" )
6660 return None
6661 except Exception:
6662 main.log.exception( self.name + ": Uncaught exception!" )
6663 main.cleanAndExit()
6664
6665 def t3( self, sAddr, dAddr, ipv6=False ):
6666 """
You Wang54b1d672018-06-11 16:44:13 -07006667 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006668 Options:
6669 sAddr: IP address of the source host
6670 dAddr: IP address of the destination host
6671 """
6672 try:
You Wang54b1d672018-06-11 16:44:13 -07006673 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6674 assert cmdList is not None, "composeT3Command returned None"
6675 t3Output = ""
6676 for cmdStr in cmdList:
6677 handle = self.sendline( cmdStr )
6678 assert handle is not None, "Error in sendline"
6679 assert "Command not found:" not in handle, handle
6680 assert "Unsupported command:" not in handle, handle
6681 assert "Error executing command" not in handle, handle
6682 assert "Tracing packet" in handle
6683 t3Output += handle
6684 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006685 except AssertionError:
6686 main.log.exception( "" )
6687 return None
6688 except pexpect.EOF:
6689 main.log.error( self.name + ": EOF exception found" )
6690 main.log.error( self.name + ": " + self.handle.before )
6691 main.cleanAndExit()
6692 except Exception:
6693 main.log.exception( self.name + ": Uncaught exception!" )
6694 main.cleanAndExit()