blob: 41b6c24f14f1c810bb36fb47e9334f21aef5c4bf [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07004OCT 13 2014
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005Copyright 2014 Open Networking Foundation (ONF)
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07006
7Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
8the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
9or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
10
11 TestON is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 2 of the License, or
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000014 (at your option) any later version.
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070015
16 TestON is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with TestON. If not, see <http://www.gnu.org/licenses/>.
23"""
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000024
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070025"""
andrewonlab95ce8322014-10-13 14:12:04 -040026This driver enters the onos> prompt to issue commands.
27
kelvin8ec71442015-01-15 16:57:00 -080028Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -040029functions and document properly.
30
31If you are a contributor to the driver, please
32list your email here for future contact:
33
34jhall@onlab.us
35andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040036shreya@onlab.us
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +000037jeremyr@opennetworking.org
kelvin8ec71442015-01-15 16:57:00 -080038"""
andrewonlab95ce8322014-10-13 14:12:04 -040039import pexpect
40import re
Jon Hall30b82fa2015-03-04 17:15:43 -080041import json
42import types
Jon Hallbd16b922015-03-26 17:53:15 -070043import time
kelvin-onlaba4074292015-07-09 15:19:49 -070044import os
andrewonlab95ce8322014-10-13 14:12:04 -040045from drivers.common.clidriver import CLI
You Wangdb8cd0a2016-05-26 15:19:45 -070046from core.graph import Graph
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -070047from cStringIO import StringIO
48from itertools import izip
andrewonlab95ce8322014-10-13 14:12:04 -040049
kelvin8ec71442015-01-15 16:57:00 -080050class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040051
kelvin8ec71442015-01-15 16:57:00 -080052 def __init__( self ):
53 """
54 Initialize client
55 """
Jon Hallefbd9792015-03-05 16:11:36 -080056 self.name = None
57 self.home = None
58 self.handle = None
Devin Limdc78e202017-06-09 18:30:07 -070059 self.karafUser = None
60 self.karafPass = None
Jon Hall6c9e2da2018-11-06 12:01:23 -080061 self.karafPrompt = "sdn@root >" # FIXME: make configurable
You Wangdb8cd0a2016-05-26 15:19:45 -070062 self.graph = Graph()
Devin Limdc78e202017-06-09 18:30:07 -070063 super( OnosCliDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080064
Jeremy Ronquillo82705492017-10-18 14:19:55 -070065 def checkOptions( self, var, defaultVar ):
Devin Limdc78e202017-06-09 18:30:07 -070066 if var is None or var == "":
67 return defaultVar
68 return var
Jeremy Ronquillo82705492017-10-18 14:19:55 -070069
kelvin8ec71442015-01-15 16:57:00 -080070 def connect( self, **connectargs ):
71 """
andrewonlab95ce8322014-10-13 14:12:04 -040072 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080073 """
andrewonlab95ce8322014-10-13 14:12:04 -040074 try:
75 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080076 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070077 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040078 for key in self.options:
79 if key == "home":
Devin Limdc78e202017-06-09 18:30:07 -070080 self.home = self.options[ key ]
81 elif key == "karaf_username":
82 self.karafUser = self.options[ key ]
83 elif key == "karaf_password":
84 self.karafPass = self.options[ key ]
85
Jeremy Ronquillo82705492017-10-18 14:19:55 -070086 self.home = self.checkOptions( self.home, "~/onos" )
87 self.karafUser = self.checkOptions( self.karafUser, self.user_name )
88 self.karafPass = self.checkOptions( self.karafPass, self.pwd )
andrewonlab95ce8322014-10-13 14:12:04 -040089
kelvin-onlaba4074292015-07-09 15:19:49 -070090 for key in self.options:
91 if key == 'onosIp':
92 self.onosIp = self.options[ 'onosIp' ]
93 break
94
kelvin8ec71442015-01-15 16:57:00 -080095 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070096
97 try:
Jon Hallc6793552016-01-19 14:18:37 -080098 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070099 self.ip_address = os.getenv( str( self.ip_address ) )
100 else:
101 main.log.info( self.name +
102 ": Trying to connect to " +
103 self.ip_address )
104
105 except KeyError:
106 main.log.info( "Invalid host name," +
107 " connecting to local host instead" )
108 self.ip_address = 'localhost'
109 except Exception as inst:
110 main.log.error( "Uncaught exception: " + str( inst ) )
111
kelvin8ec71442015-01-15 16:57:00 -0800112 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800113 user_name=self.user_name,
114 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800115 port=self.port,
116 pwd=self.pwd,
117 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400118
kelvin8ec71442015-01-15 16:57:00 -0800119 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700120 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400121 if self.handle:
122 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800123 else:
124 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400125 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800126 except TypeError:
127 main.log.exception( self.name + ": Object not as expected" )
128 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400129 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800130 main.log.error( self.name + ": EOF exception found" )
131 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700132 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800133 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800134 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700135 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400136
kelvin8ec71442015-01-15 16:57:00 -0800137 def disconnect( self ):
138 """
andrewonlab95ce8322014-10-13 14:12:04 -0400139 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800140 """
Jon Halld61331b2015-02-17 16:35:47 -0800141 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400142 try:
Jon Hall61282e32015-03-19 11:34:11 -0700143 if self.handle:
144 i = self.logout()
145 if i == main.TRUE:
146 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700147 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700148 self.handle.sendline( "exit" )
149 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800150 except TypeError:
151 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800152 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400153 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800154 main.log.error( self.name + ": EOF exception found" )
155 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700156 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700157 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700158 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800159 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800160 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400161 response = main.FALSE
162 return response
163
kelvin8ec71442015-01-15 16:57:00 -0800164 def logout( self ):
165 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500166 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700167 Returns main.TRUE if exited CLI and
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000168 main.FALSE on timeout (not guranteed you are disconnected)
Jon Hall61282e32015-03-19 11:34:11 -0700169 None on TypeError
170 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800171 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500172 try:
Jon Hall61282e32015-03-19 11:34:11 -0700173 if self.handle:
174 self.handle.sendline( "" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800175 i = self.handle.expect( [ self.karafPrompt, self.prompt, pexpect.TIMEOUT ],
Jon Hall61282e32015-03-19 11:34:11 -0700176 timeout=10 )
177 if i == 0: # In ONOS CLI
178 self.handle.sendline( "logout" )
Devin Limdc78e202017-06-09 18:30:07 -0700179 j = self.handle.expect( [ self.prompt,
Jon Hallbfe00002016-04-05 10:23:54 -0700180 "Command not found:",
181 pexpect.TIMEOUT ] )
182 if j == 0: # Successfully logged out
183 return main.TRUE
184 elif j == 1 or j == 2:
185 # ONOS didn't fully load, and logout command isn't working
186 # or the command timed out
187 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700188 try:
Devin Limdc78e202017-06-09 18:30:07 -0700189 self.handle.expect( self.prompt )
Jon Hall64ab3bd2016-05-13 11:29:44 -0700190 except pexpect.TIMEOUT:
191 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700192 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700193 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700194 main.log.warn( "Unknown repsonse to logout command: '{}'",
195 repr( self.handle.before ) )
196 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700197 elif i == 1: # not in CLI
198 return main.TRUE
199 elif i == 3: # Timeout
200 return main.FALSE
201 else:
andrewonlab9627f432014-11-14 12:45:10 -0500202 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800203 except TypeError:
204 main.log.exception( self.name + ": Object not as expected" )
205 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500206 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800207 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700208 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700209 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700210 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700211 main.log.error( self.name +
212 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800213 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800214 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700215 main.cleanAndExit()
andrewonlab38d2b4a2014-11-13 16:28:47 -0500216
kelvin-onlabd3b64892015-01-20 13:26:24 -0800217 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800218 """
andrewonlab95ce8322014-10-13 14:12:04 -0400219 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800220
andrewonlab95ce8322014-10-13 14:12:04 -0400221 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800222 """
andrewonlab95ce8322014-10-13 14:12:04 -0400223 try:
224 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800225 main.log.error( "Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700226 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400227 else:
kelvin8ec71442015-01-15 16:57:00 -0800228 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800229 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800230 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400231 # and that this driver will have to change accordingly
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700232 self.handle.expect( str( cellname ) )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800233 handleBefore = self.handle.before
234 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800235 # Get the rest of the handle
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700236 self.handle.sendline( "" )
237 self.handle.expect( self.prompt )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800238 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400239
kelvin-onlabd3b64892015-01-20 13:26:24 -0800240 main.log.info( "Cell call returned: " + handleBefore +
241 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400242
243 return main.TRUE
244
Jon Halld4d4b372015-01-28 16:02:41 -0800245 except TypeError:
246 main.log.exception( self.name + ": Object not as expected" )
247 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400248 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800249 main.log.error( self.name + ": eof exception found" )
250 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700251 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800252 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800253 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700254 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -0800255
pingping-lin57a56ce2015-05-20 16:43:48 -0700256 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800257 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800258 """
Jon Hallefbd9792015-03-05 16:11:36 -0800259 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800260 by user would be used to set the current karaf shell idle timeout.
261 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800262 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800263 Below is an example to start a session with 60 seconds idle timeout
264 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800265
Hari Krishna25d42f72015-01-05 15:08:28 -0800266 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800268
kelvin-onlabd3b64892015-01-20 13:26:24 -0800269 Note: karafTimeout is left as str so that this could be read
270 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800271 """
You Wangf69ab392016-01-26 16:34:38 -0800272 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400273 try:
Jon Hall67253832016-12-05 09:47:13 -0800274 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800275 self.handle.sendline( "" )
276 x = self.handle.expect( [
Jon Hall6c9e2da2018-11-06 12:01:23 -0800277 self.prompt, self.karafPrompt ], commandlineTimeout )
andrewonlab48829f62014-11-17 13:49:01 -0500278 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800279 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500280 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400281
Jon Hall67253832016-12-05 09:47:13 -0800282 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800283 if waitForStart:
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800284 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
285 startCliCommand = "onos-wait-for-start "
Chiyu Chengef109502016-11-21 15:51:38 -0800286 else:
287 startCliCommand = "onos "
288 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800289 i = self.handle.expect( [
Jon Hall6c9e2da2018-11-06 12:01:23 -0800290 self.karafPrompt,
pingping-lin57a56ce2015-05-20 16:43:48 -0700291 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400292
293 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800294 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800295 if karafTimeout: # FIXME: This doesn't look right
kelvin8ec71442015-01-15 16:57:00 -0800296 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800297 "config:property-set -p org.apache.karaf.shell\
298 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800299 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700300 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800301 self.handle.sendline( startCliCommand + str( ONOSIp ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800302 self.handle.expect( self.karafPrompt )
303 main.log.debug( self.handle.before )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400304 return main.TRUE
305 else:
kelvin8ec71442015-01-15 16:57:00 -0800306 # If failed, send ctrl+c to process and try again
307 main.log.info( "Starting CLI failed. Retrying..." )
308 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800309 self.handle.sendline( startCliCommand + str( ONOSIp ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800310 i = self.handle.expect( [ self.karafPrompt, pexpect.TIMEOUT ],
kelvin8ec71442015-01-15 16:57:00 -0800311 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400312 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800313 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800314 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800315 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800316 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800317 "config:property-set -p org.apache.karaf.shell\
318 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800319 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700320 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800321 self.handle.sendline( startCliCommand + str( ONOSIp ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800322 self.handle.expect( self.karafPrompt )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400323 return main.TRUE
324 else:
kelvin8ec71442015-01-15 16:57:00 -0800325 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800326 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400327 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400328
Jon Halld4d4b372015-01-28 16:02:41 -0800329 except TypeError:
330 main.log.exception( self.name + ": Object not as expected" )
331 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400332 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800333 main.log.error( self.name + ": EOF exception found" )
334 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700335 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800336 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800337 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700338 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400339
suibin zhang116647a2016-05-06 16:30:09 -0700340 def startCellCli( self, karafTimeout="",
341 commandlineTimeout=10, onosStartTimeout=60 ):
342 """
343 Start CLI on onos ecll handle.
344
345 karafTimeout is an optional argument. karafTimeout value passed
346 by user would be used to set the current karaf shell idle timeout.
347 Note that when ever this property is modified the shell will exit and
348 the subsequent login would reflect new idle timeout.
349 Below is an example to start a session with 60 seconds idle timeout
350 ( input value is in milliseconds ):
351
352 tValue = "60000"
353
354 Note: karafTimeout is left as str so that this could be read
355 and passed to startOnosCli from PARAMS file as str.
356 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000357
suibin zhang116647a2016-05-06 16:30:09 -0700358 try:
359 self.handle.sendline( "" )
360 x = self.handle.expect( [
Jon Hall6c9e2da2018-11-06 12:01:23 -0800361 self.prompt, self.karafPrompt ], commandlineTimeout )
suibin zhang116647a2016-05-06 16:30:09 -0700362
363 if x == 1:
364 main.log.info( "ONOS cli is already running" )
365 return main.TRUE
366
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800367 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
suibin zhang116647a2016-05-06 16:30:09 -0700368 self.handle.sendline( "/opt/onos/bin/onos" )
369 i = self.handle.expect( [
Jon Hall6c9e2da2018-11-06 12:01:23 -0800370 self.karafPrompt,
suibin zhang116647a2016-05-06 16:30:09 -0700371 pexpect.TIMEOUT ], onosStartTimeout )
372
373 if i == 0:
374 main.log.info( self.name + " CLI Started successfully" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800375 if karafTimeout: # FIXME: This doesn't look right
suibin zhang116647a2016-05-06 16:30:09 -0700376 self.handle.sendline(
377 "config:property-set -p org.apache.karaf.shell\
378 sshIdleTimeout " +
379 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700380 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700381 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800382 self.handle.expect( self.karafPrompt )
383 main.log.debug( self.handle.before )
suibin zhang116647a2016-05-06 16:30:09 -0700384 return main.TRUE
385 else:
386 # If failed, send ctrl+c to process and try again
387 main.log.info( "Starting CLI failed. Retrying..." )
388 self.handle.send( "\x03" )
389 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800390 i = self.handle.expect( [ self.karafPrompt, pexpect.TIMEOUT ],
suibin zhang116647a2016-05-06 16:30:09 -0700391 timeout=30 )
392 if i == 0:
393 main.log.info( self.name + " CLI Started " +
394 "successfully after retry attempt" )
395 if karafTimeout:
396 self.handle.sendline(
397 "config:property-set -p org.apache.karaf.shell\
398 sshIdleTimeout " +
399 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700400 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700401 self.handle.sendline( "/opt/onos/bin/onos" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800402 self.handle.expect( self.karafPrompt )
suibin zhang116647a2016-05-06 16:30:09 -0700403 return main.TRUE
404 else:
405 main.log.error( "Connection to CLI " +
406 self.name + " timeout" )
407 return main.FALSE
408
409 except TypeError:
410 main.log.exception( self.name + ": Object not as expected" )
411 return None
412 except pexpect.EOF:
413 main.log.error( self.name + ": EOF exception found" )
414 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700415 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700416 except Exception:
417 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700418 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700419
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800420 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800421 """
422 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800423 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800424 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700425 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800426 Available level: DEBUG, TRACE, INFO, WARN, ERROR
427 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800428 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800429 """
430 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800431 lvlStr = ""
432 if level:
433 lvlStr = "--level=" + level
434
kelvin-onlab338f5512015-02-06 10:53:16 -0800435 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700436 self.handle.expect( "log:log" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800437 self.handle.expect( self.karafPrompt )
kelvin-onlabfb521662015-02-27 09:52:40 -0800438
kelvin-onlab9f541032015-02-04 16:19:53 -0800439 response = self.handle.before
440 if re.search( "Error", response ):
441 return main.FALSE
442 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700443 except pexpect.TIMEOUT:
444 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700445 if noExit:
446 main.cleanup()
447 return None
448 else:
Devin Lim44075962017-08-11 10:56:37 -0700449 main.cleanAndExit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800450 except pexpect.EOF:
451 main.log.error( self.name + ": EOF exception found" )
452 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700453 if noExit:
454 main.cleanup()
455 return None
456 else:
Devin Lim44075962017-08-11 10:56:37 -0700457 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800458 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800459 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700460 if noExit:
461 main.cleanup()
462 return None
463 else:
Devin Lim44075962017-08-11 10:56:37 -0700464 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400465
Jon Hall0e240372018-05-02 11:21:57 -0700466 def clearBuffer( self, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800467 """
Jon Hall0e240372018-05-02 11:21:57 -0700468 Test cli connection and clear any left over output in the buffer
469 Optional Arguments:
470 debug - Defaults to False. If True, will enable debug logging.
471 timeout - Defaults to 10. Amount of time in seconds for a command to return
472 before a timeout.
473 noExit - Defaults to False. If True, will not exit TestON in the event of a
kelvin8ec71442015-01-15 16:57:00 -0800474 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400475 try:
Jon Halla495f562016-05-16 18:03:26 -0700476 # Try to reconnect if disconnected from cli
477 self.handle.sendline( "" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800478 i = self.handle.expect( [ self.karafPrompt, self.prompt, pexpect.TIMEOUT ] )
Jon Hall0e240372018-05-02 11:21:57 -0700479 response = self.handle.before
Jon Halla495f562016-05-16 18:03:26 -0700480 if i == 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700481 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700482 if self.onosIp:
483 main.log.warn( "Trying to reconnect " + self.onosIp )
484 reconnectResult = self.startOnosCli( self.onosIp )
485 if reconnectResult:
486 main.log.info( self.name + ": onos cli session reconnected." )
487 else:
488 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700489 if noExit:
490 return None
491 else:
Devin Lim44075962017-08-11 10:56:37 -0700492 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700493 else:
Devin Lim44075962017-08-11 10:56:37 -0700494 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700495 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700496 main.log.warn( "Timeout when testing cli responsiveness" )
497 main.log.debug( self.handle.before )
498 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Hall6c9e2da2018-11-06 12:01:23 -0800499 self.handle.expect( self.karafPrompt )
Jon Halla495f562016-05-16 18:03:26 -0700500
Jon Hall0e240372018-05-02 11:21:57 -0700501 response += self.handle.before
Jon Hall14a03b52016-05-11 12:07:30 -0700502 if debug:
Jon Hall0e240372018-05-02 11:21:57 -0700503 main.log.debug( self.name + ": Raw output from sending ''" )
504 main.log.debug( self.name + ": " + repr( response ) )
505 except pexpect.TIMEOUT:
506 main.log.error( self.name + ": ONOS timeout" )
507 main.log.debug( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700508 self.handle.send( "\x03" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800509 self.handle.expect( self.karafPrompt )
Jon Hall0e240372018-05-02 11:21:57 -0700510 return None
511 except pexpect.EOF:
512 main.log.error( self.name + ": EOF exception found" )
513 main.log.error( self.name + ": " + self.handle.before )
514 if noExit:
515 return None
516 else:
517 main.cleanAndExit()
518 except Exception:
519 main.log.exception( self.name + ": Uncaught exception!" )
520 if noExit:
521 return None
522 else:
523 main.cleanAndExit()
524
Jon Hall6c9e2da2018-11-06 12:01:23 -0800525 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True ):
Jon Hall0e240372018-05-02 11:21:57 -0700526 """
527 A wrapper around pexpect's sendline/expect. Will return all the output from a given command
528
529 Required Arguments:
530 cmdStr - String to send to the pexpect session
531
532 Optional Arguments:
533 showResponse - Defaults to False. If True will log the response.
534 debug - Defaults to False. If True, will enable debug logging.
535 timeout - Defaults to 10. Amount of time in seconds for a command to return
536 before a timeout.
537 noExit - Defaults to False. If True, will not exit TestON in the event of a
538 closed channel, but instead return None
Jon Hall6c9e2da2018-11-06 12:01:23 -0800539 relaxedRegex - Defaults to True. If there is a pipe in the command send, will only try to match the last part of the piped command.
Jon Hall0e240372018-05-02 11:21:57 -0700540
541 Warning: There are no sanity checking to commands sent using this method.
542
543 """
544 try:
545 # Try to reconnect if disconnected from cli
546 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
547 if debug:
548 # NOTE: This adds an average of .4 seconds per call
Jon Hall14a03b52016-05-11 12:07:30 -0700549 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700550 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800551 self.handle.sendline( cmdStr )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800552 self.handle.expect( self.karafPrompt, timeout )
Jon Hall63604932015-02-26 17:09:50 -0800553 response = self.handle.before
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000554 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800555 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700556 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700557 main.log.debug( self.name + ": Raw output" )
558 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700559
Jon Hall6c9e2da2018-11-06 12:01:23 -0800560 # Remove control codes from karaf 4.2.1
Jon Hall39e3ffe2018-12-05 11:40:29 -0800561 karafEscape = re.compile( r"('(0|1)~\'|\r\r\r\n\x1b\[A\x1b\[79C(x)?|\x1b(>|=)|\x1b\[90m~)" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800562 response = karafEscape.sub( '', response )
563 if debug:
564 main.log.debug( self.name + ": karafEscape output" )
565 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700566 # Remove ANSI color control strings from output
Jon Hall6c9e2da2018-11-06 12:01:23 -0800567 ansiEscape = re.compile( r'((\x9b|\x1b\[)[0-?]*[ -/]*[@-~])' )
Jon Hall63604932015-02-26 17:09:50 -0800568 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700569 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700570 main.log.debug( self.name + ": ansiEscape output" )
571 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700572
Jon Hall6c9e2da2018-11-06 12:01:23 -0800573 # Remove ANSI color control strings from output
574 backspaceEscape = re.compile( r'((..\x08\x08)|(.|\s)\x08)' )
575 response = backspaceEscape.sub( '', response )
576 if debug:
577 main.log.debug( self.name + ": backspaceEscape output" )
578 main.log.debug( self.name + ": " + repr( response ) )
579
kelvin-onlabfb521662015-02-27 09:52:40 -0800580 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000581 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700582 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700583 main.log.debug( self.name + ": Removed extra returns " +
584 "from output" )
585 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700586
587 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800588 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700589 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700590 main.log.debug( self.name + ": parsed and stripped output" )
591 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700592
Jon Hall63604932015-02-26 17:09:50 -0800593 # parse for just the output, remove the cmd from response
Jon Hallce0d70b2018-12-11 11:01:32 -0800594 cmdPattern = cmdStr.strip()
595 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
596 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800597 if relaxedRegex:
Jon Hallce0d70b2018-12-11 11:01:32 -0800598 cmdPattern = cmdPattern.split( '|' )[ -1 ].strip()
599 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
600 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800601 # This was added because karaf 4.2 is stripping some characters from the command echo
Jon Hallce0d70b2018-12-11 11:01:32 -0800602 output = response.split( cmdPattern, 1 )
Jon Hall39e3ffe2018-12-05 11:40:29 -0800603 if len( output ) < 2:
604 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800605 cmdPattern = cmdPattern[ -5: ]
606 main.log.debug( "REGEX PATTERN SET TO: " + repr( cmdPattern ) +
607 "\nSENT COMMAND STRING WAS: " + repr( cmdStr ) )
608 output = response.split( cmdPattern, 1 )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800609 else:
Jon Hallce0d70b2018-12-11 11:01:32 -0800610 output = response.split( cmdPattern, 1 )
611 if len( output ) < 2: # TODO: Should we do this without the relaxedRegex flag?
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800612 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800613 output = response.split( cmdPattern[ -5: ], 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700614 if output:
615 if debug:
616 main.log.debug( self.name + ": split output" )
617 for r in output:
618 main.log.debug( self.name + ": " + repr( r ) )
Jon Hallce0d70b2018-12-11 11:01:32 -0800619 if len( output ) == 1:
620 main.log.error( "Could not remove sent command echo from output" )
621 return output
Jon Hall0e240372018-05-02 11:21:57 -0700622 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800623 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800624 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700625 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800626 return output
GlennRCed771242016-01-13 17:02:47 -0800627 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700628 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800629 if debug:
630 main.log.debug( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700631 self.handle.send( "\x03" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800632 self.handle.expect( self.karafPrompt )
GlennRCed771242016-01-13 17:02:47 -0800633 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700634 except IndexError:
635 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700636 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700637 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800638 except TypeError:
639 main.log.exception( self.name + ": Object not as expected" )
640 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400641 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800642 main.log.error( self.name + ": EOF exception found" )
643 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700644 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700645 return None
646 else:
Devin Lim44075962017-08-11 10:56:37 -0700647 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800648 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800649 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700650 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700651 return None
652 else:
Devin Lim44075962017-08-11 10:56:37 -0700653 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400654
Jon Halld5a94fb2018-11-13 14:32:23 -0800655 def lineCount( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True ):
656 """
657 A wrapper around sendline(). Will return the number of lines returned or None on error
658
659 Required Arguments:
660 cmdStr - String to send to the pexpect session
661
662 Optional Arguments:
663 showResponse - Defaults to False. If True will log the response.
664 debug - Defaults to False. If True, will enable debug logging.
665 timeout - Defaults to 10. Amount of time in seconds for a command to return
666 before a timeout.
667 noExit - Defaults to False. If True, will not exit TestON in the event of a
668 closed channel, but instead return None
669 relaxedRegex - Defaults to True. If there is a pipe in the command send, will only try to match the last part of the piped command.
670
671 Warning: There are no sanity checking to commands sent using this method.
672
673 """
674 try:
675 numLines = self.sendline( cmdStr, showResponse, debug, timeout, noExit, relaxedRegex )
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800676 parsed = re.search( "(\d+)\s+(\d+)", numLines )
677 if not parsed:
678 main.log.error( "Warning, output of karaf's wc may have changed" )
679 return None
680 return parsed.group( 1 )
Jon Halld5a94fb2018-11-13 14:32:23 -0800681 except IndexError:
682 main.log.exception( self.name + ": Object not as expected" )
Jon Hallce0d70b2018-12-11 11:01:32 -0800683 main.log.debug( "response: {}".format( repr( numLines ) ) )
Jon Halld5a94fb2018-11-13 14:32:23 -0800684 return None
685 except TypeError:
686 main.log.exception( self.name + ": Object not as expected" )
687 return None
688 except Exception:
689 main.log.exception( self.name + ": Uncaught exception!" )
690 if noExit:
691 return None
692 else:
693 main.cleanAndExit()
694
kelvin8ec71442015-01-15 16:57:00 -0800695 # IMPORTANT NOTE:
696 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800697 # the cli command changing 'a:b' with 'aB'.
698 # Ex ) onos:topology > onosTopology
699 # onos:links > onosLinks
700 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800701
kelvin-onlabd3b64892015-01-20 13:26:24 -0800702 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800703 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400704 Adds a new cluster node by ID and address information.
705 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800706 * nodeId
707 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400708 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800709 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800710 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400711 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800712 cmdStr = "add-node " + str( nodeId ) + " " +\
713 str( ONOSIp ) + " " + str( tcpPort )
714 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700715 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800716 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800717 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700718 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800719 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800720 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400721 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800722 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400723 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800724 except AssertionError:
725 main.log.exception( "" )
726 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800727 except TypeError:
728 main.log.exception( self.name + ": Object not as expected" )
729 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400730 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800731 main.log.error( self.name + ": EOF exception found" )
732 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700733 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800734 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800735 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700736 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400737
kelvin-onlabd3b64892015-01-20 13:26:24 -0800738 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800739 """
andrewonlab86dc3082014-10-13 18:18:38 -0400740 Removes a cluster by ID
741 Issues command: 'remove-node [<node-id>]'
742 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800743 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800744 """
andrewonlab86dc3082014-10-13 18:18:38 -0400745 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400746
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700748 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700749 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800750 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700751 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700752 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700753 main.log.error( handle )
754 return main.FALSE
755 else:
756 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800757 except AssertionError:
758 main.log.exception( "" )
759 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800760 except TypeError:
761 main.log.exception( self.name + ": Object not as expected" )
762 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400763 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800764 main.log.error( self.name + ": EOF exception found" )
765 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700766 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800767 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800768 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700769 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400770
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700771 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800772 """
andrewonlab7c211572014-10-15 16:45:20 -0400773 List the nodes currently visible
774 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700775 Optional argument:
776 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800777 """
andrewonlab7c211572014-10-15 16:45:20 -0400778 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700779 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700780 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700781 cmdStr += " -j"
782 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700783 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800784 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700785 return output
Jon Hallc6793552016-01-19 14:18:37 -0800786 except AssertionError:
787 main.log.exception( "" )
788 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800789 except TypeError:
790 main.log.exception( self.name + ": Object not as expected" )
791 return None
andrewonlab7c211572014-10-15 16:45:20 -0400792 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800793 main.log.error( self.name + ": EOF exception found" )
794 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700795 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800796 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800797 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700798 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400799
kelvin8ec71442015-01-15 16:57:00 -0800800 def topology( self ):
801 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700802 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700803 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700804 Return:
805 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800806 """
andrewonlab95ce8322014-10-13 14:12:04 -0400807 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700808 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800809 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800810 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800811 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700812 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400813 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800814 except AssertionError:
815 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800816 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800817 except TypeError:
818 main.log.exception( self.name + ": Object not as expected" )
819 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400820 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800821 main.log.error( self.name + ": EOF exception found" )
822 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700823 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800824 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800825 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700826 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800827
jenkins7ead5a82015-03-13 10:28:21 -0700828 def deviceRemove( self, deviceId ):
829 """
830 Removes particular device from storage
831
832 TODO: refactor this function
833 """
834 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700835 cmdStr = "device-remove " + str( deviceId )
836 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800837 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800838 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700839 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700840 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700841 main.log.error( handle )
842 return main.FALSE
843 else:
844 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800845 except AssertionError:
846 main.log.exception( "" )
847 return None
jenkins7ead5a82015-03-13 10:28:21 -0700848 except TypeError:
849 main.log.exception( self.name + ": Object not as expected" )
850 return None
851 except pexpect.EOF:
852 main.log.error( self.name + ": EOF exception found" )
853 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700854 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700855 except Exception:
856 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700857 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700858
You Wang3b9689a2018-08-30 12:24:00 -0700859 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800860 """
Jon Hall7b02d952014-10-17 20:14:54 -0400861 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400862 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800863 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800864 """
andrewonlab86dc3082014-10-13 18:18:38 -0400865 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700866 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800867 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700868 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700869 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800870 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800871 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700872 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800873 except AssertionError:
874 main.log.exception( "" )
875 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800876 except TypeError:
877 main.log.exception( self.name + ": Object not as expected" )
878 return None
andrewonlab7c211572014-10-15 16:45:20 -0400879 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800880 main.log.error( self.name + ": EOF exception found" )
881 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700882 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800883 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800884 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700885 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400886
kelvin-onlabd3b64892015-01-20 13:26:24 -0800887 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800888 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800889 This balances the devices across all controllers
890 by issuing command: 'onos> onos:balance-masters'
891 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800892 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800893 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800894 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700895 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800896 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800897 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700898 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700899 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700900 main.log.error( handle )
901 return main.FALSE
902 else:
903 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800904 except AssertionError:
905 main.log.exception( "" )
906 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800907 except TypeError:
908 main.log.exception( self.name + ": Object not as expected" )
909 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800910 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800911 main.log.error( self.name + ": EOF exception found" )
912 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700913 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800914 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800915 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700916 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800917
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000918 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700919 """
920 Returns the output of the masters command.
921 Optional argument:
922 * jsonFormat - boolean indicating if you want output in json
923 """
924 try:
925 cmdStr = "onos:masters"
926 if jsonFormat:
927 cmdStr += " -j"
928 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700929 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800930 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700931 return output
Jon Hallc6793552016-01-19 14:18:37 -0800932 except AssertionError:
933 main.log.exception( "" )
934 return None
acsmars24950022015-07-30 18:00:43 -0700935 except TypeError:
936 main.log.exception( self.name + ": Object not as expected" )
937 return None
938 except pexpect.EOF:
939 main.log.error( self.name + ": EOF exception found" )
940 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700941 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700942 except Exception:
943 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700944 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700945
Jon Hallc6793552016-01-19 14:18:37 -0800946 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700947 """
948 Uses the master command to check that the devices' leadership
949 is evenly divided
950
951 Dependencies: checkMasters() and summary()
952
Jon Hall6509dbf2016-06-21 17:01:17 -0700953 Returns main.TRUE if the devices are balanced
954 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700955 Exits on Exception
956 Returns None on TypeError
957 """
958 try:
Jon Hallc6793552016-01-19 14:18:37 -0800959 summaryOutput = self.summary()
960 totalDevices = json.loads( summaryOutput )[ "devices" ]
961 except ( TypeError, ValueError ):
962 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
963 return None
964 try:
acsmars24950022015-07-30 18:00:43 -0700965 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800966 mastersOutput = self.checkMasters()
967 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700968 first = masters[ 0 ][ "size" ]
969 for master in masters:
970 totalOwnedDevices += master[ "size" ]
971 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
972 main.log.error( "Mastership not balanced" )
973 main.log.info( "\n" + self.checkMasters( False ) )
974 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700975 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700976 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700977 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800978 except ( TypeError, ValueError ):
979 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700980 return None
981 except pexpect.EOF:
982 main.log.error( self.name + ": EOF exception found" )
983 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700984 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700985 except Exception:
986 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700987 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700988
YPZhangfebf7302016-05-24 16:45:56 -0700989 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800990 """
Jon Halle8217482014-10-17 13:49:14 -0400991 Lists all core links
992 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800993 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800994 """
Jon Halle8217482014-10-17 13:49:14 -0400995 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700996 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800997 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700998 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700999 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001000 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001001 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001002 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001003 except AssertionError:
1004 main.log.exception( "" )
1005 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001006 except TypeError:
1007 main.log.exception( self.name + ": Object not as expected" )
1008 return None
Jon Halle8217482014-10-17 13:49:14 -04001009 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001010 main.log.error( self.name + ": EOF exception found" )
1011 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001012 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001013 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001014 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001015 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001016
You Wang3b9689a2018-08-30 12:24:00 -07001017 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001018 """
Jon Halle8217482014-10-17 13:49:14 -04001019 Lists all ports
1020 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001021 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001022 """
Jon Halle8217482014-10-17 13:49:14 -04001023 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001024 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001025 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001026 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -07001027 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001028 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001029 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001030 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001031 except AssertionError:
1032 main.log.exception( "" )
1033 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001034 except TypeError:
1035 main.log.exception( self.name + ": Object not as expected" )
1036 return None
Jon Halle8217482014-10-17 13:49:14 -04001037 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001038 main.log.error( self.name + ": EOF exception found" )
1039 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001040 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001041 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001042 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001043 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001044
kelvin-onlabd3b64892015-01-20 13:26:24 -08001045 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001046 """
Jon Hall983a1702014-10-28 18:44:22 -04001047 Lists all devices and the controllers with roles assigned to them
1048 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001049 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001050 """
andrewonlab7c211572014-10-15 16:45:20 -04001051 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001052 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001054 cmdStr += " -j"
1055 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001056 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001057 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001058 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001059 except AssertionError:
1060 main.log.exception( "" )
1061 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001062 except TypeError:
1063 main.log.exception( self.name + ": Object not as expected" )
1064 return None
Jon Hall983a1702014-10-28 18:44:22 -04001065 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001066 main.log.error( self.name + ": EOF exception found" )
1067 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001068 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001069 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001070 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001071 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -04001072
kelvin-onlabd3b64892015-01-20 13:26:24 -08001073 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001074 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001075 Given the a string containing the json representation of the "roles"
1076 cli command and a partial or whole device id, returns a json object
1077 containing the roles output for the first device whose id contains
1078 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001079
1080 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001081 A dict of the role assignments for the given device or
1082 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001083 """
Jon Hall983a1702014-10-28 18:44:22 -04001084 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001085 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001086 return None
1087 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001088 rawRoles = self.roles()
1089 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001090 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001091 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001092 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001094 return device
1095 return None
Jon Hallc6793552016-01-19 14:18:37 -08001096 except ( TypeError, ValueError ):
1097 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001098 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001099 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001100 main.log.error( self.name + ": EOF exception found" )
1101 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001102 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001103 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001104 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001105 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001106
kelvin-onlabd3b64892015-01-20 13:26:24 -08001107 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001108 """
Jon Hall94fd0472014-12-08 11:52:42 -08001109 Iterates through each device and checks if there is a master assigned
1110 Returns: main.TRUE if each device has a master
1111 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001112 """
Jon Hall94fd0472014-12-08 11:52:42 -08001113 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001114 rawRoles = self.roles()
1115 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001116 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001118 # print device
1119 if device[ 'master' ] == "none":
1120 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001121 return main.FALSE
1122 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001123 except ( TypeError, ValueError ):
1124 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001125 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001127 main.log.error( self.name + ": EOF exception found" )
1128 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001129 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001130 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001131 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001132 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001133
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001135 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001136 Returns string of paths, and the cost.
1137 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001138 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001139 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001140 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1141 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001142 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001143 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001144 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001145 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001146 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001147 else:
kelvin8ec71442015-01-15 16:57:00 -08001148 path = handle.split( ";" )[ 0 ]
1149 cost = handle.split( ";" )[ 1 ]
1150 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001151 except AssertionError:
1152 main.log.exception( "" )
1153 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001154 except TypeError:
1155 main.log.exception( self.name + ": Object not as expected" )
1156 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001157 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001158 main.log.error( self.name + ": EOF exception found" )
1159 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001160 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001161 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001162 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001163 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001164
kelvin-onlabd3b64892015-01-20 13:26:24 -08001165 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001166 """
Jon Hallffb386d2014-11-21 13:43:38 -08001167 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001168 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001169 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001170 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001171 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001172 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001173 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001174 cmdStr += " -j"
1175 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001176 if handle:
1177 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001178 # TODO: Maybe make this less hardcoded
1179 # ConsistentMap Exceptions
1180 assert "org.onosproject.store.service" not in handle
1181 # Node not leader
1182 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001183 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001184 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001185 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001186 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001187 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001188 except TypeError:
1189 main.log.exception( self.name + ": Object not as expected" )
1190 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001191 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001192 main.log.error( self.name + ": EOF exception found" )
1193 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001194 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001195 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001196 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001197 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001198
kelvin-onlabd3b64892015-01-20 13:26:24 -08001199 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001200 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001201 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001202
Jon Hallefbd9792015-03-05 16:11:36 -08001203 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001204 partial mac address
1205
Jon Hall42db6dc2014-10-24 19:03:48 -04001206 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001207 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001208 try:
kelvin8ec71442015-01-15 16:57:00 -08001209 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001210 return None
1211 else:
1212 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001213 rawHosts = self.hosts()
1214 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001215 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001216 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001217 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001218 if not host:
1219 pass
1220 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001221 return host
1222 return None
Jon Hallc6793552016-01-19 14:18:37 -08001223 except ( TypeError, ValueError ):
1224 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001225 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001226 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001227 main.log.error( self.name + ": EOF exception found" )
1228 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001229 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001230 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001231 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001232 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001233
kelvin-onlabd3b64892015-01-20 13:26:24 -08001234 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001235 """
1236 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001237 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001238
andrewonlab3f0a4af2014-10-17 12:25:14 -04001239 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001240 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001241 IMPORTANT:
1242 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001243 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001244 Furthermore, it assumes that value of VLAN is '-1'
1245 Description:
kelvin8ec71442015-01-15 16:57:00 -08001246 Converts mininet hosts ( h1, h2, h3... ) into
1247 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1248 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001249 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001250 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001251
kelvin-onlabd3b64892015-01-20 13:26:24 -08001252 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001253 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001254 hostHex = hex( int( host ) ).zfill( 12 )
1255 hostHex = str( hostHex ).replace( 'x', '0' )
1256 i = iter( str( hostHex ) )
1257 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1258 hostHex = hostHex + "/-1"
1259 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001260
kelvin-onlabd3b64892015-01-20 13:26:24 -08001261 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001262
Jon Halld4d4b372015-01-28 16:02:41 -08001263 except TypeError:
1264 main.log.exception( self.name + ": Object not as expected" )
1265 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001266 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001267 main.log.error( self.name + ": EOF exception found" )
1268 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001269 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001270 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001271 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001272 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001273
You Wangbc898b82018-05-03 16:22:34 -07001274 def verifyHostLocation( self, hostIp, location ):
1275 """
1276 Description:
1277 Verify the host given is discovered in all locations expected
1278 Required:
1279 hostIp: IP address of the host
1280 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1281 Could be a string or list
1282 Returns:
1283 main.TRUE if host is discovered on all locations provided
1284 main.FALSE otherwise
1285 """
1286 import json
1287 locations = [ location ] if isinstance( location, str ) else location
1288 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1289 try:
1290 hosts = self.hosts()
1291 hosts = json.loads( hosts )
1292 targetHost = None
1293 for host in hosts:
1294 if hostIp in host[ "ipAddresses" ]:
1295 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001296 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001297 result = main.TRUE
1298 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1299 for loc in locations:
1300 discovered = False
1301 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001302 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1303 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001304 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001305 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001306 break
1307 if discovered:
1308 locationsDiscovered.remove( locDiscovered )
1309 else:
1310 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1311 result = main.FALSE
1312 if locationsDiscovered:
1313 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1314 result = main.FALSE
1315 return result
1316 except KeyError:
1317 main.log.exception( self.name + ": host data not as expected: " + hosts )
1318 return None
1319 except pexpect.EOF:
1320 main.log.error( self.name + ": EOF exception found" )
1321 main.log.error( self.name + ": " + self.handle.before )
1322 main.cleanAndExit()
1323 except Exception:
1324 main.log.exception( self.name + ": Uncaught exception" )
1325 return None
1326
You Wang53dba1e2018-02-02 17:45:44 -08001327 def verifyHostIp( self, hostList=[], prefix="" ):
1328 """
1329 Description:
1330 Verify that all hosts have IP address assigned to them
1331 Optional:
1332 hostList: If specified, verifications only happen to the hosts
1333 in hostList
1334 prefix: at least one of the ip address assigned to the host
1335 needs to have the specified prefix
1336 Returns:
1337 main.TRUE if all hosts have specific IP address assigned;
1338 main.FALSE otherwise
1339 """
1340 import json
1341 try:
1342 hosts = self.hosts()
1343 hosts = json.loads( hosts )
1344 if not hostList:
1345 hostList = [ host[ "id" ] for host in hosts ]
1346 for host in hosts:
1347 hostId = host[ "id" ]
1348 if hostId not in hostList:
1349 continue
1350 ipList = host[ "ipAddresses" ]
1351 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1352 if not ipList:
1353 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1354 else:
1355 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1356 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1357 else:
1358 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1359 hostList.remove( hostId )
1360 if hostList:
1361 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1362 return main.FALSE
1363 else:
1364 return main.TRUE
1365 except KeyError:
1366 main.log.exception( self.name + ": host data not as expected: " + hosts )
1367 return None
1368 except pexpect.EOF:
1369 main.log.error( self.name + ": EOF exception found" )
1370 main.log.error( self.name + ": " + self.handle.before )
1371 main.cleanAndExit()
1372 except Exception:
1373 main.log.exception( self.name + ": Uncaught exception" )
1374 return None
1375
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001376 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001377 """
andrewonlabe6745342014-10-17 14:29:13 -04001378 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001379 * hostIdOne: ONOS host id for host1
1380 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001381 Optional:
1382 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001383 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001384 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001385 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001386 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001387 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001388 Returns:
1389 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001390 """
andrewonlabe6745342014-10-17 14:29:13 -04001391 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001392 cmdStr = "add-host-intent "
1393 if vlanId:
1394 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001395 if setVlan:
1396 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001397 if encap:
1398 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001399 if bandwidth:
1400 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001401 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001402 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001403 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001404 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001405 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001406 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001407 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001408 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001409 else:
1410 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001411 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001412 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001413 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001414 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001415 else:
1416 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001417 main.log.debug( "Response from ONOS was: " +
1418 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001419 return None
Jon Hallc6793552016-01-19 14:18:37 -08001420 except AssertionError:
1421 main.log.exception( "" )
1422 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001423 except TypeError:
1424 main.log.exception( self.name + ": Object not as expected" )
1425 return None
andrewonlabe6745342014-10-17 14:29:13 -04001426 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001427 main.log.error( self.name + ": EOF exception found" )
1428 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001429 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001430 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001431 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001432 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001433
kelvin-onlabd3b64892015-01-20 13:26:24 -08001434 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001435 """
andrewonlab7b31d232014-10-24 13:31:47 -04001436 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001437 * ingressDevice: device id of ingress device
1438 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001439 Optional:
1440 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001441 Description:
1442 Adds an optical intent by specifying an ingress and egress device
1443 Returns:
1444 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001445 """
andrewonlab7b31d232014-10-24 13:31:47 -04001446 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001447 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1448 " " + str( egressDevice )
1449 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001450 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001451 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001452 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001453 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001454 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001455 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001456 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001457 main.log.info( "Optical intent installed between " +
1458 str( ingressDevice ) + " and " +
1459 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001460 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001461 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001462 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001463 else:
1464 main.log.error( "Error, intent ID not found" )
1465 return None
Jon Hallc6793552016-01-19 14:18:37 -08001466 except AssertionError:
1467 main.log.exception( "" )
1468 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001469 except TypeError:
1470 main.log.exception( self.name + ": Object not as expected" )
1471 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001472 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001473 main.log.error( self.name + ": EOF exception found" )
1474 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001475 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001476 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001477 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001478 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001479
kelvin-onlabd3b64892015-01-20 13:26:24 -08001480 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001481 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001482 ingressDevice,
1483 egressDevice,
1484 portIngress="",
1485 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001486 ethType="",
1487 ethSrc="",
1488 ethDst="",
1489 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001490 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001491 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001492 ipProto="",
1493 ipSrc="",
1494 ipDst="",
1495 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001496 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001497 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001498 setVlan="",
1499 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001500 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001501 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001502 * ingressDevice: device id of ingress device
1503 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001504 Optional:
1505 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001506 * ethSrc: specify ethSrc ( i.e. src mac addr )
1507 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001508 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001509 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001510 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001511 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001512 * ipSrc: specify ip source address
1513 * ipDst: specify ip destination address
1514 * tcpSrc: specify tcp source port
1515 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001516 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001517 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001518 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001519 Description:
kelvin8ec71442015-01-15 16:57:00 -08001520 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001521 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001522 Returns:
1523 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001524
Jon Halle3f39ff2015-01-13 11:50:53 -08001525 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001526 options developers provide for point-to-point
1527 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001528 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001529 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001530 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001531
Jeremy Songsterff553672016-05-12 17:06:23 -07001532 if ethType:
1533 cmd += " --ethType " + str( ethType )
1534 if ethSrc:
1535 cmd += " --ethSrc " + str( ethSrc )
1536 if ethDst:
1537 cmd += " --ethDst " + str( ethDst )
1538 if bandwidth:
1539 cmd += " --bandwidth " + str( bandwidth )
1540 if lambdaAlloc:
1541 cmd += " --lambda "
1542 if ipProto:
1543 cmd += " --ipProto " + str( ipProto )
1544 if ipSrc:
1545 cmd += " --ipSrc " + str( ipSrc )
1546 if ipDst:
1547 cmd += " --ipDst " + str( ipDst )
1548 if tcpSrc:
1549 cmd += " --tcpSrc " + str( tcpSrc )
1550 if tcpDst:
1551 cmd += " --tcpDst " + str( tcpDst )
1552 if vlanId:
1553 cmd += " -v " + str( vlanId )
1554 if setVlan:
1555 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001556 if encap:
1557 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001558 if protected:
1559 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001560
kelvin8ec71442015-01-15 16:57:00 -08001561 # Check whether the user appended the port
1562 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001563 if "/" in ingressDevice:
1564 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001565 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001566 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001567 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001568 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001569 # Would it make sense to throw an exception and exit
1570 # the test?
1571 return None
andrewonlab36af3822014-11-18 17:48:18 -05001572
kelvin8ec71442015-01-15 16:57:00 -08001573 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 str( ingressDevice ) + "/" +\
1575 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001576
kelvin-onlabd3b64892015-01-20 13:26:24 -08001577 if "/" in egressDevice:
1578 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001579 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001580 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001581 main.log.error( "You must specify the egress port" )
1582 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001583
kelvin8ec71442015-01-15 16:57:00 -08001584 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001585 str( egressDevice ) + "/" +\
1586 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001587
kelvin-onlab898a6c62015-01-16 14:13:53 -08001588 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001589 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001590 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001591 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001592 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001593 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001594 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001595 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001596 # TODO: print out all the options in this message?
1597 main.log.info( "Point-to-point intent installed between " +
1598 str( ingressDevice ) + " and " +
1599 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001600 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001601 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001602 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001603 else:
1604 main.log.error( "Error, intent ID not found" )
1605 return None
Jon Hallc6793552016-01-19 14:18:37 -08001606 except AssertionError:
1607 main.log.exception( "" )
1608 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001609 except TypeError:
1610 main.log.exception( self.name + ": Object not as expected" )
1611 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001612 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001613 main.log.error( self.name + ": EOF exception found" )
1614 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001615 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001616 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001617 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001618 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001619
kelvin-onlabd3b64892015-01-20 13:26:24 -08001620 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001621 self,
shahshreyac2f97072015-03-19 17:04:29 -07001622 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001623 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001624 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001625 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001626 ethType="",
1627 ethSrc="",
1628 ethDst="",
1629 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001630 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001631 ipProto="",
1632 ipSrc="",
1633 ipDst="",
1634 tcpSrc="",
1635 tcpDst="",
1636 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001637 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001638 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001639 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001640 partial=False,
1641 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001642 """
shahshreyad0c80432014-12-04 16:56:05 -08001643 Note:
shahshreya70622b12015-03-19 17:19:00 -07001644 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001645 is same. That is, all ingress devices include port numbers
1646 with a "/" or all ingress devices could specify device
1647 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001648 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001649 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001650 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001651 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001652 Optional:
1653 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001654 * ethSrc: specify ethSrc ( i.e. src mac addr )
1655 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001656 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001657 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001658 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001659 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001660 * ipSrc: specify ip source address
1661 * ipDst: specify ip destination address
1662 * tcpSrc: specify tcp source port
1663 * tcpDst: specify tcp destination port
1664 * setEthSrc: action to Rewrite Source MAC Address
1665 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001666 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001667 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001668 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001669 Description:
kelvin8ec71442015-01-15 16:57:00 -08001670 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001671 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001672 Returns:
1673 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001674
Jon Halle3f39ff2015-01-13 11:50:53 -08001675 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001676 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001677 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001678 """
shahshreyad0c80432014-12-04 16:56:05 -08001679 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001680 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001681
Jeremy Songsterff553672016-05-12 17:06:23 -07001682 if ethType:
1683 cmd += " --ethType " + str( ethType )
1684 if ethSrc:
1685 cmd += " --ethSrc " + str( ethSrc )
1686 if ethDst:
1687 cmd += " --ethDst " + str( ethDst )
1688 if bandwidth:
1689 cmd += " --bandwidth " + str( bandwidth )
1690 if lambdaAlloc:
1691 cmd += " --lambda "
1692 if ipProto:
1693 cmd += " --ipProto " + str( ipProto )
1694 if ipSrc:
1695 cmd += " --ipSrc " + str( ipSrc )
1696 if ipDst:
1697 cmd += " --ipDst " + str( ipDst )
1698 if tcpSrc:
1699 cmd += " --tcpSrc " + str( tcpSrc )
1700 if tcpDst:
1701 cmd += " --tcpDst " + str( tcpDst )
1702 if setEthSrc:
1703 cmd += " --setEthSrc " + str( setEthSrc )
1704 if setEthDst:
1705 cmd += " --setEthDst " + str( setEthDst )
1706 if vlanId:
1707 cmd += " -v " + str( vlanId )
1708 if setVlan:
1709 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001710 if partial:
1711 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001712 if encap:
1713 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001714
kelvin8ec71442015-01-15 16:57:00 -08001715 # Check whether the user appended the port
1716 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001717
1718 if portIngressList is None:
1719 for ingressDevice in ingressDeviceList:
1720 if "/" in ingressDevice:
1721 cmd += " " + str( ingressDevice )
1722 else:
1723 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001724 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001725 # TODO: perhaps more meaningful return
1726 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001727 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001728 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001729 for ingressDevice, portIngress in zip( ingressDeviceList,
1730 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001731 cmd += " " + \
1732 str( ingressDevice ) + "/" +\
1733 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001734 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001735 main.log.error( "Device list and port list does not " +
1736 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001737 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001738 if "/" in egressDevice:
1739 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001740 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001741 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001742 main.log.error( "You must specify " +
1743 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001744 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001745
kelvin8ec71442015-01-15 16:57:00 -08001746 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001747 str( egressDevice ) + "/" +\
1748 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001749 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001750 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001751 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001752 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001753 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001754 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001755 "intent" )
1756 return None
shahshreyad0c80432014-12-04 16:56:05 -08001757 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001758 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001759 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001760 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001761 else:
1762 main.log.error( "Error, intent ID not found" )
1763 return None
Jon Hallc6793552016-01-19 14:18:37 -08001764 except AssertionError:
1765 main.log.exception( "" )
1766 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001767 except TypeError:
1768 main.log.exception( self.name + ": Object not as expected" )
1769 return None
1770 except pexpect.EOF:
1771 main.log.error( self.name + ": EOF exception found" )
1772 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001773 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001774 except Exception:
1775 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001776 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001777
1778 def addSinglepointToMultipointIntent(
1779 self,
1780 ingressDevice,
1781 egressDeviceList,
1782 portIngress="",
1783 portEgressList=None,
1784 ethType="",
1785 ethSrc="",
1786 ethDst="",
1787 bandwidth="",
1788 lambdaAlloc=False,
1789 ipProto="",
1790 ipSrc="",
1791 ipDst="",
1792 tcpSrc="",
1793 tcpDst="",
1794 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001795 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001796 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001797 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001798 partial=False,
1799 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001800 """
1801 Note:
1802 This function assumes the format of all egress devices
1803 is same. That is, all egress devices include port numbers
1804 with a "/" or all egress devices could specify device
1805 ids and port numbers seperately.
1806 Required:
1807 * EgressDeviceList: List of device ids of egress device
1808 ( Atleast 2 eress devices required in the list )
1809 * ingressDevice: device id of ingress device
1810 Optional:
1811 * ethType: specify ethType
1812 * ethSrc: specify ethSrc ( i.e. src mac addr )
1813 * ethDst: specify ethDst ( i.e. dst mac addr )
1814 * bandwidth: specify bandwidth capacity of link
1815 * lambdaAlloc: if True, intent will allocate lambda
1816 for the specified intent
1817 * ipProto: specify ip protocol
1818 * ipSrc: specify ip source address
1819 * ipDst: specify ip destination address
1820 * tcpSrc: specify tcp source port
1821 * tcpDst: specify tcp destination port
1822 * setEthSrc: action to Rewrite Source MAC Address
1823 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001824 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001825 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001826 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001827 Description:
1828 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1829 specifying device id's and optional fields
1830 Returns:
1831 A string of the intent id or None on error
1832
1833 NOTE: This function may change depending on the
1834 options developers provide for singlepoint-to-multipoint
1835 intent via cli
1836 """
1837 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001838 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001839
Jeremy Songsterff553672016-05-12 17:06:23 -07001840 if ethType:
1841 cmd += " --ethType " + str( ethType )
1842 if ethSrc:
1843 cmd += " --ethSrc " + str( ethSrc )
1844 if ethDst:
1845 cmd += " --ethDst " + str( ethDst )
1846 if bandwidth:
1847 cmd += " --bandwidth " + str( bandwidth )
1848 if lambdaAlloc:
1849 cmd += " --lambda "
1850 if ipProto:
1851 cmd += " --ipProto " + str( ipProto )
1852 if ipSrc:
1853 cmd += " --ipSrc " + str( ipSrc )
1854 if ipDst:
1855 cmd += " --ipDst " + str( ipDst )
1856 if tcpSrc:
1857 cmd += " --tcpSrc " + str( tcpSrc )
1858 if tcpDst:
1859 cmd += " --tcpDst " + str( tcpDst )
1860 if setEthSrc:
1861 cmd += " --setEthSrc " + str( setEthSrc )
1862 if setEthDst:
1863 cmd += " --setEthDst " + str( setEthDst )
1864 if vlanId:
1865 cmd += " -v " + str( vlanId )
1866 if setVlan:
1867 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001868 if partial:
1869 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001870 if encap:
1871 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001872
1873 # Check whether the user appended the port
1874 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001875
kelvin-onlabb9408212015-04-01 13:34:04 -07001876 if "/" in ingressDevice:
1877 cmd += " " + str( ingressDevice )
1878 else:
1879 if not portIngress:
1880 main.log.error( "You must specify " +
1881 "the Ingress port" )
1882 return main.FALSE
1883
1884 cmd += " " +\
1885 str( ingressDevice ) + "/" +\
1886 str( portIngress )
1887
1888 if portEgressList is None:
1889 for egressDevice in egressDeviceList:
1890 if "/" in egressDevice:
1891 cmd += " " + str( egressDevice )
1892 else:
1893 main.log.error( "You must specify " +
1894 "the egress port" )
1895 # TODO: perhaps more meaningful return
1896 return main.FALSE
1897 else:
1898 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001899 for egressDevice, portEgress in zip( egressDeviceList,
1900 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001901 cmd += " " + \
1902 str( egressDevice ) + "/" +\
1903 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001904 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001905 main.log.error( "Device list and port list does not " +
1906 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001907 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001908 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001909 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001910 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001911 # If error, return error message
1912 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001913 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001914 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001915 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001916 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001917 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001918 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001919 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001920 else:
1921 main.log.error( "Error, intent ID not found" )
1922 return None
Jon Hallc6793552016-01-19 14:18:37 -08001923 except AssertionError:
1924 main.log.exception( "" )
1925 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001926 except TypeError:
1927 main.log.exception( self.name + ": Object not as expected" )
1928 return None
shahshreyad0c80432014-12-04 16:56:05 -08001929 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001930 main.log.error( self.name + ": EOF exception found" )
1931 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001932 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001933 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001934 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001935 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001936
Hari Krishna9e232602015-04-13 17:29:08 -07001937 def addMplsIntent(
1938 self,
1939 ingressDevice,
1940 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001941 ingressPort="",
1942 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001943 ethType="",
1944 ethSrc="",
1945 ethDst="",
1946 bandwidth="",
1947 lambdaAlloc=False,
1948 ipProto="",
1949 ipSrc="",
1950 ipDst="",
1951 tcpSrc="",
1952 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001953 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001954 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001955 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001956 """
1957 Required:
1958 * ingressDevice: device id of ingress device
1959 * egressDevice: device id of egress device
1960 Optional:
1961 * ethType: specify ethType
1962 * ethSrc: specify ethSrc ( i.e. src mac addr )
1963 * ethDst: specify ethDst ( i.e. dst mac addr )
1964 * bandwidth: specify bandwidth capacity of link
1965 * lambdaAlloc: if True, intent will allocate lambda
1966 for the specified intent
1967 * ipProto: specify ip protocol
1968 * ipSrc: specify ip source address
1969 * ipDst: specify ip destination address
1970 * tcpSrc: specify tcp source port
1971 * tcpDst: specify tcp destination port
1972 * ingressLabel: Ingress MPLS label
1973 * egressLabel: Egress MPLS label
1974 Description:
1975 Adds MPLS intent by
1976 specifying device id's and optional fields
1977 Returns:
1978 A string of the intent id or None on error
1979
1980 NOTE: This function may change depending on the
1981 options developers provide for MPLS
1982 intent via cli
1983 """
1984 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001985 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001986
Jeremy Songsterff553672016-05-12 17:06:23 -07001987 if ethType:
1988 cmd += " --ethType " + str( ethType )
1989 if ethSrc:
1990 cmd += " --ethSrc " + str( ethSrc )
1991 if ethDst:
1992 cmd += " --ethDst " + str( ethDst )
1993 if bandwidth:
1994 cmd += " --bandwidth " + str( bandwidth )
1995 if lambdaAlloc:
1996 cmd += " --lambda "
1997 if ipProto:
1998 cmd += " --ipProto " + str( ipProto )
1999 if ipSrc:
2000 cmd += " --ipSrc " + str( ipSrc )
2001 if ipDst:
2002 cmd += " --ipDst " + str( ipDst )
2003 if tcpSrc:
2004 cmd += " --tcpSrc " + str( tcpSrc )
2005 if tcpDst:
2006 cmd += " --tcpDst " + str( tcpDst )
2007 if ingressLabel:
2008 cmd += " --ingressLabel " + str( ingressLabel )
2009 if egressLabel:
2010 cmd += " --egressLabel " + str( egressLabel )
2011 if priority:
2012 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07002013
2014 # Check whether the user appended the port
2015 # or provided it as an input
2016 if "/" in ingressDevice:
2017 cmd += " " + str( ingressDevice )
2018 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002019 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002020 main.log.error( "You must specify the ingress port" )
2021 return None
2022
2023 cmd += " " + \
2024 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002025 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07002026
2027 if "/" in egressDevice:
2028 cmd += " " + str( egressDevice )
2029 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002030 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002031 main.log.error( "You must specify the egress port" )
2032 return None
2033
2034 cmd += " " +\
2035 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002036 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07002037
2038 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08002039 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002040 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07002041 # If error, return error message
2042 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002043 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07002044 return None
2045 else:
2046 # TODO: print out all the options in this message?
2047 main.log.info( "MPLS intent installed between " +
2048 str( ingressDevice ) + " and " +
2049 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002050 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07002051 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002052 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07002053 else:
2054 main.log.error( "Error, intent ID not found" )
2055 return None
Jon Hallc6793552016-01-19 14:18:37 -08002056 except AssertionError:
2057 main.log.exception( "" )
2058 return None
Hari Krishna9e232602015-04-13 17:29:08 -07002059 except TypeError:
2060 main.log.exception( self.name + ": Object not as expected" )
2061 return None
2062 except pexpect.EOF:
2063 main.log.error( self.name + ": EOF exception found" )
2064 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002065 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002066 except Exception:
2067 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002068 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002069
Jon Hallefbd9792015-03-05 16:11:36 -08002070 def removeIntent( self, intentId, app='org.onosproject.cli',
2071 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002072 """
shahshreya1c818fc2015-02-26 13:44:08 -08002073 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07002074 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08002075 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07002076 -p or --purge: Purge the intent from the store after removal
2077
Jon Halle3f39ff2015-01-13 11:50:53 -08002078 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002079 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002080 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002081 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002082 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002083 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002084 if purge:
2085 cmdStr += " -p"
2086 if sync:
2087 cmdStr += " -s"
2088
2089 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002090 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002091 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002092 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002093 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002094 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002095 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002096 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002097 # TODO: Should this be main.TRUE
2098 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002099 except AssertionError:
2100 main.log.exception( "" )
2101 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002102 except TypeError:
2103 main.log.exception( self.name + ": Object not as expected" )
2104 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002105 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002106 main.log.error( self.name + ": EOF exception found" )
2107 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002108 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002109 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002110 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002111 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002112
YPZhangfebf7302016-05-24 16:45:56 -07002113 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002114 """
2115 Description:
2116 Remove all the intents
2117 Optional args:-
2118 -s or --sync: Waits for the removal before returning
2119 -p or --purge: Purge the intent from the store after removal
2120 Returns:
2121 Returns main.TRUE if all intents are removed, otherwise returns
2122 main.FALSE; Returns None for exception
2123 """
2124 try:
2125 cmdStr = "remove-intent"
2126 if purge:
2127 cmdStr += " -p"
2128 if sync:
2129 cmdStr += " -s"
2130
2131 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002132 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002133 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002134 assert "Command not found:" not in handle, handle
2135 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002136 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002137 return main.FALSE
2138 else:
2139 return main.TRUE
2140 except AssertionError:
2141 main.log.exception( "" )
2142 return None
2143 except TypeError:
2144 main.log.exception( self.name + ": Object not as expected" )
2145 return None
2146 except pexpect.EOF:
2147 main.log.error( self.name + ": EOF exception found" )
2148 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002149 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002150 except Exception:
2151 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002152 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002153
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002154 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002155 """
2156 Purges all WITHDRAWN Intents
2157 """
2158 try:
2159 cmdStr = "purge-intents"
2160 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002161 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002162 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002163 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002164 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002165 return main.FALSE
2166 else:
2167 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002168 except AssertionError:
2169 main.log.exception( "" )
2170 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002171 except TypeError:
2172 main.log.exception( self.name + ": Object not as expected" )
2173 return None
2174 except pexpect.EOF:
2175 main.log.error( self.name + ": EOF exception found" )
2176 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002177 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002178 except Exception:
2179 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002180 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002181
Devin Lime6fe3c42017-10-18 16:28:40 -07002182 def wipeout( self ):
2183 """
2184 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2185 """
2186 try:
2187 cmdStr = "wipe-out please"
2188 handle = self.sendline( cmdStr, timeout=60 )
2189 assert handle is not None, "Error in sendline"
2190 assert "Command not found:" not in handle, handle
2191 return main.TRUE
2192 except AssertionError:
2193 main.log.exception( "" )
2194 return None
2195 except TypeError:
2196 main.log.exception( self.name + ": Object not as expected" )
2197 return None
2198 except pexpect.EOF:
2199 main.log.error( self.name + ": EOF exception found" )
2200 main.log.error( self.name + ": " + self.handle.before )
2201 main.cleanAndExit()
2202 except Exception:
2203 main.log.exception( self.name + ": Uncaught exception!" )
2204 main.cleanAndExit()
2205
kelvin-onlabd3b64892015-01-20 13:26:24 -08002206 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002207 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002208 NOTE: This method should be used after installing application:
2209 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002210 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002211 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002212 Description:
2213 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002214 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002215 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002216 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002217 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002218 cmdStr += " -j"
2219 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002220 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002221 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002222 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002223 except AssertionError:
2224 main.log.exception( "" )
2225 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002226 except TypeError:
2227 main.log.exception( self.name + ": Object not as expected" )
2228 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002229 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002230 main.log.error( self.name + ": EOF exception found" )
2231 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002232 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002233 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002234 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002235 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002236
pingping-lin54b03372015-08-13 14:43:10 -07002237 def ipv4RouteNumber( self ):
2238 """
2239 NOTE: This method should be used after installing application:
2240 onos-app-sdnip
2241 Description:
2242 Obtain the total IPv4 routes number in the system
2243 """
2244 try:
Pratik Parab57963572017-05-09 11:37:54 -07002245 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002246 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002247 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002248 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002249 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002250 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002251 except AssertionError:
2252 main.log.exception( "" )
2253 return None
2254 except ( TypeError, ValueError ):
2255 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002256 return None
2257 except pexpect.EOF:
2258 main.log.error( self.name + ": EOF exception found" )
2259 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002260 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002261 except Exception:
2262 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002263 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002264
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002265 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002266 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002267 """
2268 Description:
2269 Obtain Bandwidth Allocation Information from ONOS cli.
2270 """
2271 try:
2272 cmdStr = "allocations"
2273 if jsonFormat:
2274 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002275 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002276 assert handle is not None, "Error in sendline"
2277 assert "Command not found:" not in handle, handle
2278 return handle
2279 except AssertionError:
2280 main.log.exception( "" )
2281 return None
2282 except ( TypeError, ValueError ):
2283 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2284 return None
2285 except pexpect.EOF:
2286 main.log.error( self.name + ": EOF exception found" )
2287 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002288 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002289 except Exception:
2290 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002291 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002292
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002293 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002294 """
andrewonlabe6745342014-10-17 14:29:13 -04002295 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002296 Obtain intents from the ONOS cli.
2297 Optional:
2298 * jsonFormat: Enable output formatting in json, default to True
2299 * summary: Whether only output the intent summary, defaults to False
2300 * type: Only output a certain type of intent. This options is valid
2301 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002302 """
andrewonlabe6745342014-10-17 14:29:13 -04002303 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002304 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002305 if summary:
2306 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002307 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002308 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002309 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002310 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002311 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002312 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002313 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002314 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002315 else:
Jon Hallff566d52016-01-15 14:45:36 -08002316 intentType = ""
2317 # IF we want the summary of a specific intent type
2318 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002319 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002320 if intentType in jsonResult.keys():
2321 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002322 else:
Jon Hallff566d52016-01-15 14:45:36 -08002323 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002324 return handle
2325 else:
2326 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002327 except AssertionError:
2328 main.log.exception( "" )
2329 return None
2330 except ( TypeError, ValueError ):
2331 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002332 return None
2333 except pexpect.EOF:
2334 main.log.error( self.name + ": EOF exception found" )
2335 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002336 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002337 except Exception:
2338 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002339 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002340
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002341 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002342 """
You Wangfdcbfc42016-05-16 12:16:53 -07002343 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002344 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002345 list of intent IDs.
2346 Parameters:
2347 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002348 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002349 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002350 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002351 accepted.
2352 Returns a list of dictionaries if a list of intent IDs is accepted,
2353 and each dictionary maps 'id' to the Intent ID and 'state' to
2354 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002355 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002356
kelvin-onlab54400a92015-02-26 18:05:51 -08002357 try:
2358 state = "State is Undefined"
2359 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002360 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002361 else:
Jon Hallc6793552016-01-19 14:18:37 -08002362 rawJson = intentsJson
2363 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002364 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002365 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002366 if intentsId == intent[ 'id' ]:
2367 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002368 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002369 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002370 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002371 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002372 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002373 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002374 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002375 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002376 for intent in parsedIntentsJson:
2377 if intentsId[ i ] == intent[ 'id' ]:
2378 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002379 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002380 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002381 break
Jon Hallefbd9792015-03-05 16:11:36 -08002382 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002383 main.log.warn( "Could not find all intents in ONOS output" )
2384 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002385 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002386 else:
Jon Hall53158082017-05-18 11:17:00 -07002387 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002388 return None
Jon Hallc6793552016-01-19 14:18:37 -08002389 except ( TypeError, ValueError ):
2390 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002391 return None
2392 except pexpect.EOF:
2393 main.log.error( self.name + ": EOF exception found" )
2394 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002395 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002396 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002397 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002398 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002399
Jon Hallf539eb92017-05-22 17:18:42 -07002400 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002401 """
2402 Description:
2403 Check intents state
2404 Required:
2405 intentsId - List of intents ID to be checked
2406 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002407 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002408 state in the list.
2409 *NOTE: You can pass in a list of expected state,
2410 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002411 Return:
Jon Hall53158082017-05-18 11:17:00 -07002412 Returns main.TRUE only if all intent are the same as expected states,
2413 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002414 """
2415 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002416 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002417 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002418
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002419 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002420 intentsDict = []
2421 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002422 if isinstance( intentsId, types.StringType ) \
2423 and intent.get( 'id' ) == intentsId:
2424 intentsDict.append( intent )
2425 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002426 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002427 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002428
2429 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002430 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002431 "getting intents state" )
2432 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002433
2434 if isinstance( expectedState, types.StringType ):
2435 for intents in intentsDict:
2436 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002437 main.log.debug( self.name + " : Intent ID - " +
2438 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002439 " actual state = " +
2440 intents.get( 'state' )
2441 + " does not equal expected state = "
2442 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002443 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002444 elif isinstance( expectedState, types.ListType ):
2445 for intents in intentsDict:
2446 if not any( state == intents.get( 'state' ) for state in
2447 expectedState ):
2448 main.log.debug( self.name + " : Intent ID - " +
2449 intents.get( 'id' ) +
2450 " actual state = " +
2451 intents.get( 'state' ) +
2452 " does not equal expected states = "
2453 + str( expectedState ) )
2454 returnValue = main.FALSE
2455
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002456 if returnValue == main.TRUE:
2457 main.log.info( self.name + ": All " +
2458 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002459 " intents are in " + str( expectedState ) +
2460 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002461 return returnValue
2462 except TypeError:
2463 main.log.exception( self.name + ": Object not as expected" )
2464 return None
2465 except pexpect.EOF:
2466 main.log.error( self.name + ": EOF exception found" )
2467 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002468 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002469 except Exception:
2470 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002471 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002472
Jon Hallf539eb92017-05-22 17:18:42 -07002473 def compareBandwidthAllocations( self, expectedAllocations ):
2474 """
2475 Description:
2476 Compare the allocated bandwidth with the given allocations
2477 Required:
2478 expectedAllocations - The expected ONOS output of the allocations command
2479 Return:
2480 Returns main.TRUE only if all intent are the same as expected states,
2481 otherwise returns main.FALSE.
2482 """
2483 # FIXME: Convert these string comparisons to object comparisons
2484 try:
2485 returnValue = main.TRUE
2486 bandwidthFailed = False
2487 rawAlloc = self.allocations()
2488 expectedFormat = StringIO( expectedAllocations )
2489 ONOSOutput = StringIO( rawAlloc )
2490 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2491 str( expectedFormat ) ) )
2492
2493 for actual, expected in izip( ONOSOutput, expectedFormat ):
2494 actual = actual.rstrip()
2495 expected = expected.rstrip()
2496 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2497 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002498 marker1 = actual.find( 'allocated' )
2499 m1 = actual[ :marker1 ]
2500 marker2 = expected.find( 'allocated' )
2501 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002502 if m1 != m2:
2503 bandwidthFailed = True
2504 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2505 bandwidthFailed = True
2506 expectedFormat.close()
2507 ONOSOutput.close()
2508
2509 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002510 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002511 returnValue = main.FALSE
2512 return returnValue
2513 except TypeError:
2514 main.log.exception( self.name + ": Object not as expected" )
2515 return None
2516 except pexpect.EOF:
2517 main.log.error( self.name + ": EOF exception found" )
2518 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002519 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002520 except Exception:
2521 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002522 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002523
You Wang66518af2016-05-16 15:32:59 -07002524 def compareIntent( self, intentDict ):
2525 """
2526 Description:
2527 Compare the intent ids and states provided in the argument with all intents in ONOS
2528 Return:
2529 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2530 Arguments:
2531 intentDict: a dictionary which maps intent ids to intent states
2532 """
2533 try:
2534 intentsRaw = self.intents()
2535 intentsJson = json.loads( intentsRaw )
2536 intentDictONOS = {}
2537 for intent in intentsJson:
2538 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002539 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002540 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002541 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002542 str( len( intentDict ) ) + " expected and " +
2543 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002544 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002545 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002546 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002547 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2548 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002549 else:
2550 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2551 main.log.debug( self.name + ": intent ID - " + intentID +
2552 " expected state is " + intentDict[ intentID ] +
2553 " but actual state is " + intentDictONOS[ intentID ] )
2554 returnValue = main.FALSE
2555 intentDictONOS.pop( intentID )
2556 if len( intentDictONOS ) > 0:
2557 returnValue = main.FALSE
2558 for intentID in intentDictONOS.keys():
2559 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002560 if returnValue == main.TRUE:
2561 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2562 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002563 except KeyError:
2564 main.log.exception( self.name + ": KeyError exception found" )
2565 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002566 except ( TypeError, ValueError ):
2567 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002568 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002569 except pexpect.EOF:
2570 main.log.error( self.name + ": EOF exception found" )
2571 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002572 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002573 except Exception:
2574 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002575 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002576
YPZhang14a4aa92016-07-15 13:37:15 -07002577 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002578 """
2579 Description:
2580 Check the number of installed intents.
2581 Optional:
2582 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002583 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002584 Return:
2585 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2586 , otherwise, returns main.FALSE.
2587 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002588
GlennRCed771242016-01-13 17:02:47 -08002589 try:
2590 cmd = "intents -s -j"
2591
2592 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002593 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002594 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002595 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002596 response = json.loads( response )
2597
2598 # get total and installed number, see if they are match
2599 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002600 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002601 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2602 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002603 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002604 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2605 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002606 return main.FALSE
2607
Jon Hallc6793552016-01-19 14:18:37 -08002608 except ( TypeError, ValueError ):
2609 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002610 return None
2611 except pexpect.EOF:
2612 main.log.error( self.name + ": EOF exception found" )
2613 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002614 if noExit:
2615 return main.FALSE
2616 else:
Devin Lim44075962017-08-11 10:56:37 -07002617 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002618 except pexpect.TIMEOUT:
2619 main.log.error( self.name + ": ONOS timeout" )
2620 return None
GlennRCed771242016-01-13 17:02:47 -08002621 except Exception:
2622 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002623 if noExit:
2624 return main.FALSE
2625 else:
Devin Lim44075962017-08-11 10:56:37 -07002626 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002627
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002628 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002629 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002630 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002631 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002632 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002633 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002634 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002635 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002636 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002637 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002638 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002639 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002640 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002641 cmdStr += " -n"
2642 cmdStr += " " + state
2643 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002644 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002645 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002646 assert "Command not found:" not in handle, handle
2647 if re.search( "Error:", handle ):
2648 main.log.error( self.name + ": flows() response: " +
2649 str( handle ) )
2650 return handle
2651 except AssertionError:
2652 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002653 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002654 except TypeError:
2655 main.log.exception( self.name + ": Object not as expected" )
2656 return None
Jon Hallc6793552016-01-19 14:18:37 -08002657 except pexpect.TIMEOUT:
2658 main.log.error( self.name + ": ONOS timeout" )
2659 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002660 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002661 main.log.error( self.name + ": EOF exception found" )
2662 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002663 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002664 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002665 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002666 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002667
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002668 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002669 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002670 count = int( count ) if count else 0
2671 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002672
Jon Halle0f0b342017-04-18 11:43:47 -07002673 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002674 """
2675 Description:
GlennRCed771242016-01-13 17:02:47 -08002676 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002677 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2678 if the count of those states is 0, which means all current flows
2679 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002680 Optional:
GlennRCed771242016-01-13 17:02:47 -08002681 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002682 Return:
2683 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002684 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002685 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002686 """
2687 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002688 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002689 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002690 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002691 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002692 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002693 if rawFlows:
2694 # if we didn't get flows or flows function return None, we should return
2695 # main.Flase
2696 checkedStates.append( json.loads( rawFlows ) )
2697 else:
2698 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002699 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002700 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002701 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002702 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002703 except TypeError:
2704 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002705 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002706
GlennRCed771242016-01-13 17:02:47 -08002707 # We want to count PENDING_ADD if isPENDING is true
2708 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002709 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002710 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002711 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002712 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002713 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002714 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002715 except ( TypeError, ValueError ):
2716 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002717 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002718
YPZhang240842b2016-05-17 12:00:50 -07002719 except AssertionError:
2720 main.log.exception( "" )
2721 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002722 except pexpect.TIMEOUT:
2723 main.log.error( self.name + ": ONOS timeout" )
2724 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002725 except pexpect.EOF:
2726 main.log.error( self.name + ": EOF exception found" )
2727 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002728 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002729 except Exception:
2730 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002731 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002732
GlennRCed771242016-01-13 17:02:47 -08002733 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002734 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002735 """
andrewonlab87852b02014-11-19 18:44:19 -05002736 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002737 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002738 a specific point-to-point intent definition
2739 Required:
GlennRCed771242016-01-13 17:02:47 -08002740 * ingress: specify source dpid
2741 * egress: specify destination dpid
2742 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002743 Optional:
GlennRCed771242016-01-13 17:02:47 -08002744 * offset: the keyOffset is where the next batch of intents
2745 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002746 * noExit: If set to True, TestON will not exit if any error when issus command
2747 * getResponse: If set to True, function will return ONOS response.
2748
GlennRCed771242016-01-13 17:02:47 -08002749 Returns: If failed to push test intents, it will returen None,
2750 if successful, return true.
2751 Timeout expection will return None,
2752 TypeError will return false
2753 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002754 """
andrewonlab87852b02014-11-19 18:44:19 -05002755 try:
GlennRCed771242016-01-13 17:02:47 -08002756 if background:
2757 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002758 else:
GlennRCed771242016-01-13 17:02:47 -08002759 back = ""
2760 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002761 ingress,
2762 egress,
2763 batchSize,
2764 offset,
2765 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002766 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002767 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002768 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002769 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002770 if getResponse:
2771 return response
2772
GlennRCed771242016-01-13 17:02:47 -08002773 # TODO: We should handle if there is failure in installation
2774 return main.TRUE
2775
Jon Hallc6793552016-01-19 14:18:37 -08002776 except AssertionError:
2777 main.log.exception( "" )
2778 return None
GlennRCed771242016-01-13 17:02:47 -08002779 except pexpect.TIMEOUT:
2780 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002781 return None
andrewonlab87852b02014-11-19 18:44:19 -05002782 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002783 main.log.error( self.name + ": EOF exception found" )
2784 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002785 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002786 except TypeError:
2787 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002788 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002789 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002790 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002791 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002792
YPZhangebf9eb52016-05-12 15:20:24 -07002793 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002794 """
2795 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002796 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002797 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002798 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002799 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002800 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002801
YPZhangb5d3f832016-01-23 22:54:26 -08002802 try:
YPZhange3109a72016-02-02 11:25:37 -08002803 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002804 cmd = "flows -c added"
2805 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2806 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002807 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002808 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002809 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002810 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002811 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002812 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002813 return None
2814 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002815
You Wangd3cb2ce2016-05-16 14:01:24 -07002816 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002817 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002818 return None
2819 except pexpect.EOF:
2820 main.log.error( self.name + ": EOF exception found" )
2821 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002822 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002823 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002824 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002825 except pexpect.TIMEOUT:
2826 main.log.error( self.name + ": ONOS timeout" )
2827 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002828 except Exception:
2829 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002830 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002831 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002832 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002833
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002834 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002835 """
2836 Description:
2837 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002838 Optional:
2839 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002840 Return:
2841 The number of intents
2842 """
2843 try:
2844 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002845 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002846 if response is None:
2847 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002848 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002849 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002850 except ( TypeError, ValueError ):
2851 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002852 return None
2853 except pexpect.EOF:
2854 main.log.error( self.name + ": EOF exception found" )
2855 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002856 if noExit:
2857 return -1
2858 else:
Devin Lim44075962017-08-11 10:56:37 -07002859 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002860 except Exception:
2861 main.log.exception( self.name + ": Uncaught exception!" )
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
kelvin-onlabd3b64892015-01-20 13:26:24 -08002867 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002868 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002869 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002870 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002871 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002872 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002873 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002874 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002875 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002876 cmdStr += " -j"
2877 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002878 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002879 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002880 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002881 except AssertionError:
2882 main.log.exception( "" )
2883 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002884 except TypeError:
2885 main.log.exception( self.name + ": Object not as expected" )
2886 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002887 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002888 main.log.error( self.name + ": EOF exception found" )
2889 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002890 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002891 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002892 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002893 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002894
kelvin-onlabd3b64892015-01-20 13:26:24 -08002895 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002896 """
2897 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002898 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002899 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002900 """
andrewonlab867212a2014-10-22 20:13:38 -04002901 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002902 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002903 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002904 cmdStr += " -j"
2905 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002906 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002907 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002908 if handle:
2909 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002910 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002911 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002912 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002913 else:
2914 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002915 except AssertionError:
2916 main.log.exception( "" )
2917 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002918 except TypeError:
2919 main.log.exception( self.name + ": Object not as expected" )
2920 return None
andrewonlab867212a2014-10-22 20:13:38 -04002921 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002922 main.log.error( self.name + ": EOF exception found" )
2923 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002924 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002925 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002926 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002927 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002928
kelvin8ec71442015-01-15 16:57:00 -08002929 # Wrapper functions ****************
2930 # Wrapper functions use existing driver
2931 # functions and extends their use case.
2932 # For example, we may use the output of
2933 # a normal driver function, and parse it
2934 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002935
kelvin-onlabd3b64892015-01-20 13:26:24 -08002936 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002937 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002938 Description:
2939 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002940 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002941 try:
kelvin8ec71442015-01-15 16:57:00 -08002942 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002943 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002944 if intentsStr is None:
2945 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002946 # Convert to a dictionary
2947 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002948 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002949 for intent in intents:
2950 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002951 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002952 except TypeError:
2953 main.log.exception( self.name + ": Object not as expected" )
2954 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002955 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002956 main.log.error( self.name + ": EOF exception found" )
2957 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002958 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002959 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002960 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002961 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002962
You Wang3c276252016-09-21 15:21:36 -07002963 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002964 """
2965 Determine the number of flow rules for the given device id that are
2966 in the added state
You Wang3c276252016-09-21 15:21:36 -07002967 Params:
2968 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002969 """
2970 try:
You Wang3c276252016-09-21 15:21:36 -07002971 if core:
2972 cmdStr = "flows any " + str( deviceId ) + " | " +\
2973 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2974 else:
2975 cmdStr = "flows any " + str( deviceId ) + " | " +\
2976 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08002977 handle = self.lineCount( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002978 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002979 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002980 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002981 except AssertionError:
2982 main.log.exception( "" )
2983 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002984 except pexpect.EOF:
2985 main.log.error( self.name + ": EOF exception found" )
2986 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002987 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002988 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002989 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002990 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002991
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002992 def groupAddedCount( self, deviceId, core=False ):
2993 """
2994 Determine the number of group rules for the given device id that are
2995 in the added state
2996 Params:
2997 core: if True, only return the number of core groups added
2998 """
2999 try:
3000 if core:
3001 cmdStr = "groups any " + str( deviceId ) + " | " +\
3002 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
3003 else:
3004 cmdStr = "groups any " + str( deviceId ) + " | " +\
3005 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003006 handle = self.lineCount( cmdStr )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003007 assert handle is not None, "Error in sendline"
3008 assert "Command not found:" not in handle, handle
3009 return handle
3010 except AssertionError:
3011 main.log.exception( "" )
3012 return None
3013 except pexpect.EOF:
3014 main.log.error( self.name + ": EOF exception found" )
3015 main.log.error( self.name + ": " + self.handle.before )
3016 main.cleanAndExit()
3017 except Exception:
3018 main.log.exception( self.name + ": Uncaught exception!" )
3019 main.cleanAndExit()
3020
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003021 def addStaticRoute( self, subnet, intf):
3022 """
3023 Adds a static route to onos.
3024 Params:
3025 subnet: The subnet reaching through this route
3026 intf: The interface this route is reachable through
3027 """
3028 try:
3029 cmdStr = "route-add " + subnet + " " + intf
3030 handle = self.sendline( cmdStr )
3031 assert handle is not None, "Error in sendline"
3032 assert "Command not found:" not in handle, handle
3033 return handle
3034 except AssertionError:
3035 main.log.exception( "" )
3036 return None
3037 except pexpect.EOF:
3038 main.log.error( self.name + ": EOF exception found" )
3039 main.log.error( self.name + ": " + self.handle.before )
3040 main.cleanAndExit()
3041 except Exception:
3042 main.log.exception( self.name + ": Uncaught exception!" )
3043 main.cleanAndExit()
3044
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003045 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
3046 """
3047 Description:
3048 Check whether the number of groups for the given device id that
3049 are in ADDED state is bigger than minGroupCount.
3050 Required:
3051 * deviceId: device id to check the number of added group rules
3052 Optional:
3053 * minGroupCount: the number of groups to compare
3054 * core: if True, only check the number of core groups added
3055 * comparison: if 0, compare with greater than minFlowCount
3056 * if 1, compare with equal to minFlowCount
3057 Return:
3058 Returns the number of groups if it is bigger than minGroupCount,
3059 returns main.FALSE otherwise.
3060 """
3061 count = self.groupAddedCount( deviceId, core )
3062 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003063 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003064 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
3065
You Wangc02f3be2018-05-18 12:14:23 -07003066 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003067 """
3068 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07003069 deviceId: Id of the device from which we retrieve groups
3070 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003071 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003072 try:
You Wangc02f3be2018-05-18 12:14:23 -07003073 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
3074 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003075 assert handle is not None, "Error in sendline"
3076 assert "Command not found:" not in handle, handle
3077 return handle
3078 except AssertionError:
3079 main.log.exception( "" )
3080 return None
3081 except TypeError:
3082 main.log.exception( self.name + ": Object not as expected" )
3083 return None
3084 except pexpect.EOF:
3085 main.log.error( self.name + ": EOF exception found" )
3086 main.log.error( self.name + ": " + self.handle.before )
3087 main.cleanAndExit()
3088 except Exception:
3089 main.log.exception( self.name + ": Uncaught exception!" )
3090 main.cleanAndExit()
3091
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003092 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003093 """
3094 Description:
3095 Check whether the number of flow rules for the given device id that
3096 are in ADDED state is bigger than minFlowCount.
3097 Required:
3098 * deviceId: device id to check the number of added flow rules
3099 Optional:
3100 * minFlowCount: the number of flow rules to compare
3101 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003102 * comparison: if 0, compare with greater than minFlowCount
3103 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003104 Return:
3105 Returns the number of flow rules if it is bigger than minFlowCount,
3106 returns main.FALSE otherwise.
3107 """
3108 count = self.flowAddedCount( deviceId, core )
3109 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003110 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003111 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003112
kelvin-onlabd3b64892015-01-20 13:26:24 -08003113 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003114 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003115 Use 'devices' function to obtain list of all devices
3116 and parse the result to obtain a list of all device
3117 id's. Returns this list. Returns empty list if no
3118 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003119 List is ordered sequentially
3120
andrewonlab3e15ead2014-10-15 14:21:34 -04003121 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003122 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003123 the ids. By obtaining the list of device ids on the fly,
3124 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003125 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003126 try:
kelvin8ec71442015-01-15 16:57:00 -08003127 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003128 devicesStr = self.devices( jsonFormat=False )
3129 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003130
kelvin-onlabd3b64892015-01-20 13:26:24 -08003131 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003132 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003133 return idList
kelvin8ec71442015-01-15 16:57:00 -08003134
3135 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003136 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003137 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003138 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003139 # Split list further into arguments before and after string
3140 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003141 # append to idList
3142 for arg in tempList:
3143 idList.append( arg.split( "id=" )[ 1 ] )
3144 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003145
Jon Halld4d4b372015-01-28 16:02:41 -08003146 except TypeError:
3147 main.log.exception( self.name + ": Object not as expected" )
3148 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003149 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003150 main.log.error( self.name + ": EOF exception found" )
3151 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003152 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003153 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003154 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003155 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003156
kelvin-onlabd3b64892015-01-20 13:26:24 -08003157 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003158 """
andrewonlab7c211572014-10-15 16:45:20 -04003159 Uses 'nodes' function to obtain list of all nodes
3160 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003161 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003162 Returns:
3163 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003164 """
andrewonlab7c211572014-10-15 16:45:20 -04003165 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003166 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003167 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003168 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003169 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003170 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003171 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003172 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003173 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003174 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003175 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003176 except ( TypeError, ValueError ):
3177 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003178 return None
andrewonlab7c211572014-10-15 16:45:20 -04003179 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003180 main.log.error( self.name + ": EOF exception found" )
3181 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003182 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003183 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003184 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003185 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003186
kelvin-onlabd3b64892015-01-20 13:26:24 -08003187 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003188 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003189 Return the first device from the devices api whose 'id' contains 'dpid'
3190 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003191 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003192 try:
kelvin8ec71442015-01-15 16:57:00 -08003193 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003194 return None
3195 else:
kelvin8ec71442015-01-15 16:57:00 -08003196 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003197 rawDevices = self.devices()
3198 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003199 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003200 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003201 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3202 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003203 return device
3204 return None
Jon Hallc6793552016-01-19 14:18:37 -08003205 except ( TypeError, ValueError ):
3206 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003207 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003208 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003209 main.log.error( self.name + ": EOF exception found" )
3210 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003211 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003212 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003213 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003214 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003215
You Wang24139872016-05-03 11:48:47 -07003216 def getTopology( self, topologyOutput ):
3217 """
3218 Definition:
3219 Loads a json topology output
3220 Return:
3221 topology = current ONOS topology
3222 """
3223 import json
3224 try:
3225 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003226 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003227 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003228 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003229 except ( TypeError, ValueError ):
3230 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3231 return None
You Wang24139872016-05-03 11:48:47 -07003232 except pexpect.EOF:
3233 main.log.error( self.name + ": EOF exception found" )
3234 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003235 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003236 except Exception:
3237 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003238 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003239
Pier6a0c4de2018-03-18 16:01:30 -07003240 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003241 """
Jon Hallefbd9792015-03-05 16:11:36 -08003242 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003243 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003244 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003245
Flavio Castro82ee2f62016-06-07 15:04:12 -07003246 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003247 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003248 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003249 logLevel = level to log to.
3250 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003251
Jon Hallefbd9792015-03-05 16:11:36 -08003252 Returns: main.TRUE if the number of switches and links are correct,
3253 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003254 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003255 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003256 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003257 try:
You Wang13310252016-07-31 10:56:14 -07003258 summary = self.summary()
3259 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003260 except ( TypeError, ValueError ):
3261 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3262 return main.ERROR
3263 try:
3264 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003265 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003266 return main.ERROR
3267 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003268 # Is the number of switches is what we expected
3269 devices = topology.get( 'devices', False )
3270 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003271 nodes = summary.get( 'nodes', False )
3272 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003273 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003274 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003275 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003276 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003277 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3278 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003279 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003280 output = output + "The number of links and switches match "\
3281 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003282 result = main.TRUE
3283 else:
You Wang24139872016-05-03 11:48:47 -07003284 output = output + \
3285 "The number of links and switches does not match " + \
3286 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003287 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003288 output = output + "\n ONOS sees %i devices" % int( devices )
3289 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003290 if int( numolink ) > 0:
3291 output = output + "and %i links " % int( links )
3292 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003293 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003294 output = output + "and %i controllers " % int( nodes )
3295 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003296 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003297 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003298 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003299 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003300 else:
You Wang24139872016-05-03 11:48:47 -07003301 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003302 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003303 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003304 main.log.error( self.name + ": EOF exception found" )
3305 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003306 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003307 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003308 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003309 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003310
kelvin-onlabd3b64892015-01-20 13:26:24 -08003311 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003312 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003313 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003314 deviceId must be the id of a device as seen in the onos devices command
3315 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003316 role must be either master, standby, or none
3317
Jon Halle3f39ff2015-01-13 11:50:53 -08003318 Returns:
3319 main.TRUE or main.FALSE based on argument verification and
3320 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003321 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003322 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003323 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003324 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003325 cmdStr = "device-role " +\
3326 str( deviceId ) + " " +\
3327 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003328 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003329 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003330 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003331 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003332 if re.search( "Error", handle ):
3333 # end color output to escape any colours
3334 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003335 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003336 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003337 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003338 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003339 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003340 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003341 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003342 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003343 except AssertionError:
3344 main.log.exception( "" )
3345 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003346 except TypeError:
3347 main.log.exception( self.name + ": Object not as expected" )
3348 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003349 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003350 main.log.error( self.name + ": EOF exception found" )
3351 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003352 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003353 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003354 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003355 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003356
kelvin-onlabd3b64892015-01-20 13:26:24 -08003357 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003358 """
Jon Hall0dd09952018-04-19 09:59:11 -07003359 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003360 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003361 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003362 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003363 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003364 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003365 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003366 cmdStr += " -j"
3367 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003368 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003369 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003370 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003371 except AssertionError:
3372 main.log.exception( "" )
3373 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003374 except TypeError:
3375 main.log.exception( self.name + ": Object not as expected" )
3376 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003377 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003378 main.log.error( self.name + ": EOF exception found" )
3379 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003380 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003381 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003382 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003383 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003384
kelvin-onlabd3b64892015-01-20 13:26:24 -08003385 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003386 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003387 CLI command to get the current leader for the Election test application
3388 NOTE: Requires installation of the onos-app-election feature
3389 Returns: Node IP of the leader if one exists
3390 None if none exists
3391 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003392 """
Jon Hall94fd0472014-12-08 11:52:42 -08003393 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003394 cmdStr = "election-test-leader"
3395 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003396 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003397 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003398 # Leader
3399 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003400 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003401 nodeSearch = re.search( leaderPattern, response )
3402 if nodeSearch:
3403 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003404 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003405 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003406 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003407 # no leader
3408 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003409 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003410 nullSearch = re.search( nullPattern, response )
3411 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003412 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003413 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003414 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003415 # error
Jon Hall0e240372018-05-02 11:21:57 -07003416 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003417 ": " + "unexpected response" )
3418 main.log.error( repr( response ) )
3419 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003420 except AssertionError:
3421 main.log.exception( "" )
3422 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003423 except TypeError:
3424 main.log.exception( self.name + ": Object not as expected" )
3425 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003426 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003427 main.log.error( self.name + ": EOF exception found" )
3428 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003429 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003430 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003431 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003432 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003433
kelvin-onlabd3b64892015-01-20 13:26:24 -08003434 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003435 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003436 CLI command to run for leadership of the Election test application.
3437 NOTE: Requires installation of the onos-app-election feature
3438 Returns: Main.TRUE on success
3439 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003440 """
Jon Hall94fd0472014-12-08 11:52:42 -08003441 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003442 cmdStr = "election-test-run"
3443 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003444 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003445 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003446 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003447 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003448 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003449 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003450 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003451 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003452 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003453 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003454 # error
Jon Hall0e240372018-05-02 11:21:57 -07003455 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003456 ": " + "unexpected response" )
3457 main.log.error( repr( response ) )
3458 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003459 except AssertionError:
3460 main.log.exception( "" )
3461 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003462 except TypeError:
3463 main.log.exception( self.name + ": Object not as expected" )
3464 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003465 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003466 main.log.error( self.name + ": EOF exception found" )
3467 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003468 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003469 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003470 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003471 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003472
kelvin-onlabd3b64892015-01-20 13:26:24 -08003473 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003474 """
Jon Hall94fd0472014-12-08 11:52:42 -08003475 * CLI command to withdraw the local node from leadership election for
3476 * the Election test application.
3477 #NOTE: Requires installation of the onos-app-election feature
3478 Returns: Main.TRUE on success
3479 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003480 """
Jon Hall94fd0472014-12-08 11:52:42 -08003481 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003482 cmdStr = "election-test-withdraw"
3483 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003484 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003485 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003486 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003487 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003488 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003489 if re.search( successPattern, response ):
3490 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003491 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003492 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003493 # error
Jon Hall0e240372018-05-02 11:21:57 -07003494 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003495 self.name + ": " + "unexpected response" )
3496 main.log.error( repr( response ) )
3497 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003498 except AssertionError:
3499 main.log.exception( "" )
3500 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003501 except TypeError:
3502 main.log.exception( self.name + ": Object not as expected" )
3503 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003504 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003505 main.log.error( self.name + ": EOF exception found" )
3506 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003507 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003508 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003509 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003510 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003511
kelvin8ec71442015-01-15 16:57:00 -08003512 def getDevicePortsEnabledCount( self, dpid ):
3513 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003514 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003515 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003516 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003517 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003518 cmdStr = "onos:ports -e " + dpid + " | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003519 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003520 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003521 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003522 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003523 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003524 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003525 return output
Jon Hallc6793552016-01-19 14:18:37 -08003526 except AssertionError:
3527 main.log.exception( "" )
3528 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003529 except TypeError:
3530 main.log.exception( self.name + ": Object not as expected" )
3531 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003532 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003533 main.log.error( self.name + ": EOF exception found" )
3534 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003535 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003536 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003537 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003538 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003539
kelvin8ec71442015-01-15 16:57:00 -08003540 def getDeviceLinksActiveCount( self, dpid ):
3541 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003542 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003543 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003544 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003545 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003546 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003547 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003548 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003549 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003550 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003551 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003552 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003553 return output
Jon Hallc6793552016-01-19 14:18:37 -08003554 except AssertionError:
3555 main.log.exception( "" )
3556 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003557 except TypeError:
3558 main.log.exception( self.name + ": Object not as expected" )
3559 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003560 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003561 main.log.error( self.name + ": EOF exception found" )
3562 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003563 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003564 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003565 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003566 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003567
kelvin8ec71442015-01-15 16:57:00 -08003568 def getAllIntentIds( self ):
3569 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003570 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003571 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003572 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003573 cmdStr = "onos:intents | grep id="
3574 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003575 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003576 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003577 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003578 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003579 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003580 return output
Jon Hallc6793552016-01-19 14:18:37 -08003581 except AssertionError:
3582 main.log.exception( "" )
3583 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003584 except TypeError:
3585 main.log.exception( self.name + ": Object not as expected" )
3586 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003587 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003588 main.log.error( self.name + ": EOF exception found" )
3589 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003590 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003591 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003592 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003593 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003594
Jon Hall73509952015-02-24 16:42:56 -08003595 def intentSummary( self ):
3596 """
Jon Hallefbd9792015-03-05 16:11:36 -08003597 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003598 """
3599 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003600 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003601 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003602 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003603 states.append( intent.get( 'state', None ) )
3604 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003605 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003606 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003607 except ( TypeError, ValueError ):
3608 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003609 return None
3610 except pexpect.EOF:
3611 main.log.error( self.name + ": EOF exception found" )
3612 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003613 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003614 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003615 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003616 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003617
Jon Hall61282e32015-03-19 11:34:11 -07003618 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003619 """
3620 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003621 Optional argument:
3622 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003623 """
Jon Hall63604932015-02-26 17:09:50 -08003624 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003625 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003626 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003627 cmdStr += " -j"
3628 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003629 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003630 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003631 return output
Jon Hallc6793552016-01-19 14:18:37 -08003632 except AssertionError:
3633 main.log.exception( "" )
3634 return None
Jon Hall63604932015-02-26 17:09:50 -08003635 except TypeError:
3636 main.log.exception( self.name + ": Object not as expected" )
3637 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003638 except pexpect.EOF:
3639 main.log.error( self.name + ": EOF exception found" )
3640 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003641 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003642 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003643 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003644 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003645
acsmarsa4a4d1e2015-07-10 16:01:24 -07003646 def leaderCandidates( self, jsonFormat=True ):
3647 """
3648 Returns the output of the leaders -c command.
3649 Optional argument:
3650 * jsonFormat - boolean indicating if you want output in json
3651 """
3652 try:
3653 cmdStr = "onos:leaders -c"
3654 if jsonFormat:
3655 cmdStr += " -j"
3656 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003657 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003658 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003659 return output
Jon Hallc6793552016-01-19 14:18:37 -08003660 except AssertionError:
3661 main.log.exception( "" )
3662 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003663 except TypeError:
3664 main.log.exception( self.name + ": Object not as expected" )
3665 return None
3666 except pexpect.EOF:
3667 main.log.error( self.name + ": EOF exception found" )
3668 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003669 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003670 except Exception:
3671 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003672 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003673
Jon Hallc6793552016-01-19 14:18:37 -08003674 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003675 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003676 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003677 topic parameter and an empty list if the topic doesn't exist
3678 If no leader is elected leader in the returned list will be "none"
3679 Returns None if there is a type error processing the json object
3680 """
3681 try:
Jon Hall6e709752016-02-01 13:38:46 -08003682 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003683 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003684 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003685 assert "Command not found:" not in rawOutput, rawOutput
3686 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003687 results = []
3688 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003689 if dict[ "topic" ] == topic:
3690 leader = dict[ "leader" ]
3691 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003692 results.append( leader )
3693 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003694 return results
Jon Hallc6793552016-01-19 14:18:37 -08003695 except AssertionError:
3696 main.log.exception( "" )
3697 return None
3698 except ( TypeError, ValueError ):
3699 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003700 return None
3701 except pexpect.EOF:
3702 main.log.error( self.name + ": EOF exception found" )
3703 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003704 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003705 except Exception:
3706 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003707 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003708
Jon Hall61282e32015-03-19 11:34:11 -07003709 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003710 """
3711 Returns the output of the intent Pending map.
3712 """
Jon Hall63604932015-02-26 17:09:50 -08003713 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003714 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003715 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003716 cmdStr += " -j"
3717 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003718 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003719 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003720 return output
Jon Hallc6793552016-01-19 14:18:37 -08003721 except AssertionError:
3722 main.log.exception( "" )
3723 return None
Jon Hall63604932015-02-26 17:09:50 -08003724 except TypeError:
3725 main.log.exception( self.name + ": Object not as expected" )
3726 return None
3727 except pexpect.EOF:
3728 main.log.error( self.name + ": EOF exception found" )
3729 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003730 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003731 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003732 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003733 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003734
Jon Hall2c8959e2016-12-16 12:17:34 -08003735 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003736 """
3737 Returns the output of the raft partitions command for ONOS.
3738 """
Jon Hall61282e32015-03-19 11:34:11 -07003739 # Sample JSON
3740 # {
3741 # "leader": "tcp://10.128.30.11:7238",
3742 # "members": [
3743 # "tcp://10.128.30.11:7238",
3744 # "tcp://10.128.30.17:7238",
3745 # "tcp://10.128.30.13:7238",
3746 # ],
3747 # "name": "p1",
3748 # "term": 3
3749 # },
Jon Hall63604932015-02-26 17:09:50 -08003750 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003751 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003752 if candidates:
3753 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003754 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003755 cmdStr += " -j"
3756 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003757 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003758 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003759 return output
Jon Hallc6793552016-01-19 14:18:37 -08003760 except AssertionError:
3761 main.log.exception( "" )
3762 return None
Jon Hall63604932015-02-26 17:09:50 -08003763 except TypeError:
3764 main.log.exception( self.name + ": Object not as expected" )
3765 return None
3766 except pexpect.EOF:
3767 main.log.error( self.name + ": EOF exception found" )
3768 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003769 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003770 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003771 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003772 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003773
Jon Halle9f909e2016-09-23 10:43:12 -07003774 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003775 """
3776 Returns the output of the apps command for ONOS. This command lists
3777 information about installed ONOS applications
3778 """
3779 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003780 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003781 # "description":"ONOS OpenFlow protocol southbound providers",
3782 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003783 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003784 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003785 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003786 if summary:
3787 cmdStr += " -s"
3788 if active:
3789 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003790 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003791 cmdStr += " -j"
3792 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003793 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003794 assert "Command not found:" not in output, output
3795 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003796 return output
Jon Hallbe379602015-03-24 13:39:32 -07003797 # FIXME: look at specific exceptions/Errors
3798 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003799 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003800 return None
3801 except TypeError:
3802 main.log.exception( self.name + ": Object not as expected" )
3803 return None
3804 except pexpect.EOF:
3805 main.log.error( self.name + ": EOF exception found" )
3806 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003807 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003808 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003809 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003810 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003811
You Wangcdc51fe2018-08-12 17:14:56 -07003812 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003813 """
3814 Uses the onos:apps cli command to return the status of an application.
3815 Returns:
3816 "ACTIVE" - If app is installed and activated
3817 "INSTALLED" - If app is installed and deactivated
3818 "UNINSTALLED" - If app is not installed
3819 None - on error
3820 """
Jon Hall146f1522015-03-24 15:33:24 -07003821 try:
3822 if not isinstance( appName, types.StringType ):
3823 main.log.error( self.name + ".appStatus(): appName must be" +
3824 " a string" )
3825 return None
3826 output = self.apps( jsonFormat=True )
3827 appsJson = json.loads( output )
3828 state = None
3829 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003830 if appName == app.get( 'name' ):
3831 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003832 break
3833 if state == "ACTIVE" or state == "INSTALLED":
3834 return state
3835 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003836 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003837 return "UNINSTALLED"
3838 elif state:
3839 main.log.error( "Unexpected state from 'onos:apps': " +
3840 str( state ) )
3841 return state
Jon Hallc6793552016-01-19 14:18:37 -08003842 except ( TypeError, ValueError ):
3843 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003844 return None
3845 except pexpect.EOF:
3846 main.log.error( self.name + ": EOF exception found" )
3847 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003848 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003849 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003850 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003851 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003852
Jon Hallbe379602015-03-24 13:39:32 -07003853 def app( self, appName, option ):
3854 """
3855 Interacts with the app command for ONOS. This command manages
3856 application inventory.
3857 """
Jon Hallbe379602015-03-24 13:39:32 -07003858 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003859 # Validate argument types
3860 valid = True
3861 if not isinstance( appName, types.StringType ):
3862 main.log.error( self.name + ".app(): appName must be a " +
3863 "string" )
3864 valid = False
3865 if not isinstance( option, types.StringType ):
3866 main.log.error( self.name + ".app(): option must be a string" )
3867 valid = False
3868 if not valid:
3869 return main.FALSE
3870 # Validate Option
3871 option = option.lower()
3872 # NOTE: Install may become a valid option
3873 if option == "activate":
3874 pass
3875 elif option == "deactivate":
3876 pass
3877 elif option == "uninstall":
3878 pass
3879 else:
3880 # Invalid option
3881 main.log.error( "The ONOS app command argument only takes " +
3882 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003883 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003884 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003885 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003886 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003887 assert output is not None, "Error in sendline"
3888 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003889 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003890 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003891 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003892 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003893 elif "No such application" in output:
3894 main.log.error( "The application '" + appName +
3895 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003896 return main.FALSE
3897 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003898 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003899 str( output ) )
3900 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003901 elif "Unsupported command:" in output:
3902 main.log.error( "Incorrect command given to 'app': " +
3903 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003904 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003905 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003906 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003907 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003908 except AssertionError:
3909 main.log.exception( self.name + ": AssertionError exception found" )
3910 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003911 except TypeError:
3912 main.log.exception( self.name + ": Object not as expected" )
3913 return main.ERROR
3914 except pexpect.EOF:
3915 main.log.error( self.name + ": EOF exception found" )
3916 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003917 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003918 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003919 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003920 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003921
Jon Hallbd16b922015-03-26 17:53:15 -07003922 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003923 """
3924 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003925 appName is the hierarchical app name, not the feature name
3926 If check is True, method will check the status of the app after the
3927 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003928 Returns main.TRUE if the command was successfully sent
3929 main.FALSE if the cli responded with an error or given
3930 incorrect input
3931 """
3932 try:
3933 if not isinstance( appName, types.StringType ):
3934 main.log.error( self.name + ".activateApp(): appName must be" +
3935 " a string" )
3936 return main.FALSE
3937 status = self.appStatus( appName )
3938 if status == "INSTALLED":
3939 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003940 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003941 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003942 status = self.appStatus( appName )
3943 if status == "ACTIVE":
3944 return main.TRUE
3945 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003946 main.log.debug( "The state of application " +
3947 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003948 time.sleep( 1 )
3949 return main.FALSE
3950 else: # not 'check' or command didn't succeed
3951 return response
Jon Hall146f1522015-03-24 15:33:24 -07003952 elif status == "ACTIVE":
3953 return main.TRUE
3954 elif status == "UNINSTALLED":
3955 main.log.error( self.name + ": Tried to activate the " +
3956 "application '" + appName + "' which is not " +
3957 "installed." )
3958 else:
3959 main.log.error( "Unexpected return value from appStatus: " +
3960 str( status ) )
3961 return main.ERROR
3962 except TypeError:
3963 main.log.exception( self.name + ": Object not as expected" )
3964 return main.ERROR
3965 except pexpect.EOF:
3966 main.log.error( self.name + ": EOF exception found" )
3967 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003968 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003969 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003970 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003971 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003972
Jon Hallbd16b922015-03-26 17:53:15 -07003973 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003974 """
3975 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003976 appName is the hierarchical app name, not the feature name
3977 If check is True, method will check the status of the app after the
3978 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003979 Returns main.TRUE if the command was successfully sent
3980 main.FALSE if the cli responded with an error or given
3981 incorrect input
3982 """
3983 try:
3984 if not isinstance( appName, types.StringType ):
3985 main.log.error( self.name + ".deactivateApp(): appName must " +
3986 "be a string" )
3987 return main.FALSE
3988 status = self.appStatus( appName )
3989 if status == "INSTALLED":
3990 return main.TRUE
3991 elif status == "ACTIVE":
3992 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003993 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003994 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003995 status = self.appStatus( appName )
3996 if status == "INSTALLED":
3997 return main.TRUE
3998 else:
3999 time.sleep( 1 )
4000 return main.FALSE
4001 else: # not check or command didn't succeed
4002 return response
Jon Hall146f1522015-03-24 15:33:24 -07004003 elif status == "UNINSTALLED":
4004 main.log.warn( self.name + ": Tried to deactivate the " +
4005 "application '" + appName + "' which is not " +
4006 "installed." )
4007 return main.TRUE
4008 else:
4009 main.log.error( "Unexpected return value from appStatus: " +
4010 str( status ) )
4011 return main.ERROR
4012 except TypeError:
4013 main.log.exception( self.name + ": Object not as expected" )
4014 return main.ERROR
4015 except pexpect.EOF:
4016 main.log.error( self.name + ": EOF exception found" )
4017 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004018 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004019 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004020 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004021 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004022
Jon Hallbd16b922015-03-26 17:53:15 -07004023 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004024 """
4025 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004026 appName is the hierarchical app name, not the feature name
4027 If check is True, method will check the status of the app after the
4028 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004029 Returns main.TRUE if the command was successfully sent
4030 main.FALSE if the cli responded with an error or given
4031 incorrect input
4032 """
4033 # TODO: check with Thomas about the state machine for apps
4034 try:
4035 if not isinstance( appName, types.StringType ):
4036 main.log.error( self.name + ".uninstallApp(): appName must " +
4037 "be a string" )
4038 return main.FALSE
4039 status = self.appStatus( appName )
4040 if status == "INSTALLED":
4041 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004042 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004043 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004044 status = self.appStatus( appName )
4045 if status == "UNINSTALLED":
4046 return main.TRUE
4047 else:
4048 time.sleep( 1 )
4049 return main.FALSE
4050 else: # not check or command didn't succeed
4051 return response
Jon Hall146f1522015-03-24 15:33:24 -07004052 elif status == "ACTIVE":
4053 main.log.warn( self.name + ": Tried to uninstall the " +
4054 "application '" + appName + "' which is " +
4055 "currently active." )
4056 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004057 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004058 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004059 status = self.appStatus( appName )
4060 if status == "UNINSTALLED":
4061 return main.TRUE
4062 else:
4063 time.sleep( 1 )
4064 return main.FALSE
4065 else: # not check or command didn't succeed
4066 return response
Jon Hall146f1522015-03-24 15:33:24 -07004067 elif status == "UNINSTALLED":
4068 return main.TRUE
4069 else:
4070 main.log.error( "Unexpected return value from appStatus: " +
4071 str( status ) )
4072 return main.ERROR
4073 except TypeError:
4074 main.log.exception( self.name + ": Object not as expected" )
4075 return main.ERROR
4076 except pexpect.EOF:
4077 main.log.error( self.name + ": EOF exception found" )
4078 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004079 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004080 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004081 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004082 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004083
4084 def appIDs( self, jsonFormat=True ):
4085 """
4086 Show the mappings between app id and app names given by the 'app-ids'
4087 cli command
4088 """
4089 try:
4090 cmdStr = "app-ids"
4091 if jsonFormat:
4092 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004093 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004094 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004095 assert "Command not found:" not in output, output
4096 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004097 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004098 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004099 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004100 return None
4101 except TypeError:
4102 main.log.exception( self.name + ": Object not as expected" )
4103 return None
4104 except pexpect.EOF:
4105 main.log.error( self.name + ": EOF exception found" )
4106 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004107 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004108 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004109 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004110 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004111
4112 def appToIDCheck( self ):
4113 """
4114 This method will check that each application's ID listed in 'apps' is
4115 the same as the ID listed in 'app-ids'. The check will also check that
4116 there are no duplicate IDs issued. Note that an app ID should be
4117 a globaly unique numerical identifier for app/app-like features. Once
4118 an ID is registered, the ID is never freed up so that if an app is
4119 reinstalled it will have the same ID.
4120
4121 Returns: main.TRUE if the check passes and
4122 main.FALSE if the check fails or
4123 main.ERROR if there is some error in processing the test
4124 """
4125 try:
Jon Hall0e240372018-05-02 11:21:57 -07004126 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004127 rawJson = self.appIDs( jsonFormat=True )
4128 if rawJson:
4129 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004130 else:
Jon Hall0e240372018-05-02 11:21:57 -07004131 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4132 return main.FALSE
4133
4134 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004135 rawJson = self.apps( jsonFormat=True )
4136 if rawJson:
4137 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004138 else:
Jon Hallc6793552016-01-19 14:18:37 -08004139 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004140 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004141
Jon Hallbd16b922015-03-26 17:53:15 -07004142 result = main.TRUE
4143 for app in apps:
4144 appID = app.get( 'id' )
4145 if appID is None:
4146 main.log.error( "Error parsing app: " + str( app ) )
4147 result = main.FALSE
4148 appName = app.get( 'name' )
4149 if appName is None:
4150 main.log.error( "Error parsing app: " + str( app ) )
4151 result = main.FALSE
4152 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004153 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004154 if not current: # if ids doesn't have this id
4155 result = main.FALSE
4156 main.log.error( "'app-ids' does not have the ID for " +
4157 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004158 main.log.debug( "apps command returned: " + str( app ) +
4159 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004160 elif len( current ) > 1:
4161 # there is more than one app with this ID
4162 result = main.FALSE
4163 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004164 elif not current[ 0 ][ 'name' ] == appName:
4165 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004166 result = main.FALSE
4167 main.log.error( "'app-ids' has " + str( currentName ) +
4168 " registered under id:" + str( appID ) +
4169 " but 'apps' has " + str( appName ) )
4170 else:
4171 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004172
Jon Hallbd16b922015-03-26 17:53:15 -07004173 # now make sure that app-ids has no duplicates
4174 idsList = []
4175 namesList = []
4176 for item in ids:
4177 idsList.append( item[ 'id' ] )
4178 namesList.append( item[ 'name' ] )
4179 if len( idsList ) != len( set( idsList ) ) or\
4180 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004181 main.log.error( "'app-ids' has some duplicate entries: \n"
4182 + json.dumps( ids,
4183 sort_keys=True,
4184 indent=4,
4185 separators=( ',', ': ' ) ) )
4186 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004187 return result
Jon Hallc6793552016-01-19 14:18:37 -08004188 except ( TypeError, ValueError ):
4189 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004190 return main.ERROR
4191 except pexpect.EOF:
4192 main.log.error( self.name + ": EOF exception found" )
4193 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004194 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004195 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004196 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004197 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004198
Jon Hallfb760a02015-04-13 15:35:03 -07004199 def getCfg( self, component=None, propName=None, short=False,
4200 jsonFormat=True ):
4201 """
4202 Get configuration settings from onos cli
4203 Optional arguments:
4204 component - Optionally only list configurations for a specific
4205 component. If None, all components with configurations
4206 are displayed. Case Sensitive string.
4207 propName - If component is specified, propName option will show
4208 only this specific configuration from that component.
4209 Case Sensitive string.
4210 jsonFormat - Returns output as json. Note that this will override
4211 the short option
4212 short - Short, less verbose, version of configurations.
4213 This is overridden by the json option
4214 returns:
4215 Output from cli as a string or None on error
4216 """
4217 try:
4218 baseStr = "cfg"
4219 cmdStr = " get"
4220 componentStr = ""
4221 if component:
4222 componentStr += " " + component
4223 if propName:
4224 componentStr += " " + propName
4225 if jsonFormat:
4226 baseStr += " -j"
4227 elif short:
4228 baseStr += " -s"
4229 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004230 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004231 assert "Command not found:" not in output, output
4232 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004233 return output
4234 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004235 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004236 return None
4237 except TypeError:
4238 main.log.exception( self.name + ": Object not as expected" )
4239 return None
4240 except pexpect.EOF:
4241 main.log.error( self.name + ": EOF exception found" )
4242 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004243 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004244 except Exception:
4245 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004246 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004247
4248 def setCfg( self, component, propName, value=None, check=True ):
4249 """
4250 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004251 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004252 component - The case sensitive name of the component whose
4253 property is to be set
4254 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004255 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004256 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004257 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004258 check - Boolean, Check whether the option was successfully set this
4259 only applies when a value is given.
4260 returns:
4261 main.TRUE on success or main.FALSE on failure. If check is False,
4262 will return main.TRUE unless there is an error
4263 """
4264 try:
4265 baseStr = "cfg"
4266 cmdStr = " set " + str( component ) + " " + str( propName )
4267 if value is not None:
4268 cmdStr += " " + str( value )
4269 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004270 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004271 assert "Command not found:" not in output, output
4272 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004273 if value and check:
4274 results = self.getCfg( component=str( component ),
4275 propName=str( propName ),
4276 jsonFormat=True )
4277 # Check if current value is what we just set
4278 try:
4279 jsonOutput = json.loads( results )
4280 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004281 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004282 main.log.exception( "Error parsing cfg output" )
4283 main.log.error( "output:" + repr( results ) )
4284 return main.FALSE
4285 if current == str( value ):
4286 return main.TRUE
4287 return main.FALSE
4288 return main.TRUE
4289 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004290 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004291 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004292 except ( TypeError, ValueError ):
4293 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004294 return main.FALSE
4295 except pexpect.EOF:
4296 main.log.error( self.name + ": EOF exception found" )
4297 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004298 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004299 except Exception:
4300 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004301 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004302
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004303 def distPrimitivesSend( self, cmd ):
4304 """
4305 Function to handle sending cli commands for the distributed primitives test app
4306
4307 This command will catch some exceptions and retry the command on some
4308 specific store exceptions.
4309
4310 Required arguments:
4311 cmd - The command to send to the cli
4312 returns:
4313 string containing the cli output
4314 None on Error
4315 """
4316 try:
4317 output = self.sendline( cmd )
4318 try:
4319 assert output is not None, "Error in sendline"
4320 # TODO: Maybe make this less hardcoded
4321 # ConsistentMap Exceptions
4322 assert "org.onosproject.store.service" not in output
4323 # Node not leader
4324 assert "java.lang.IllegalStateException" not in output
4325 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004326 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004327 "command: " + str( output ) )
4328 retryTime = 30 # Conservative time, given by Madan
4329 main.log.info( "Waiting " + str( retryTime ) +
4330 "seconds before retrying." )
4331 time.sleep( retryTime ) # Due to change in mastership
4332 output = self.sendline( cmd )
4333 assert output is not None, "Error in sendline"
4334 assert "Command not found:" not in output, output
4335 assert "Error executing command" not in output, output
4336 main.log.info( self.name + ": " + output )
4337 return output
4338 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004339 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004340 return None
4341 except TypeError:
4342 main.log.exception( self.name + ": Object not as expected" )
4343 return None
4344 except pexpect.EOF:
4345 main.log.error( self.name + ": EOF exception found" )
4346 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004347 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004348 except Exception:
4349 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004350 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004351
Jon Hall390696c2015-05-05 17:13:41 -07004352 def setTestAdd( self, setName, values ):
4353 """
4354 CLI command to add elements to a distributed set.
4355 Arguments:
4356 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004357 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004358 Example usages:
4359 setTestAdd( "set1", "a b c" )
4360 setTestAdd( "set2", "1" )
4361 returns:
4362 main.TRUE on success OR
4363 main.FALSE if elements were already in the set OR
4364 main.ERROR on error
4365 """
4366 try:
4367 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004368 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004369 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4370 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004371 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004372 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004373 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004374 return main.FALSE
4375 else:
4376 main.log.error( self.name + ": setTestAdd did not" +
4377 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004378 main.log.debug( self.name + " actual: " + repr( output ) )
4379 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004380 except TypeError:
4381 main.log.exception( self.name + ": Object not as expected" )
4382 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004383 except Exception:
4384 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004385 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004386
4387 def setTestRemove( self, setName, values, clear=False, retain=False ):
4388 """
4389 CLI command to remove elements from a distributed set.
4390 Required arguments:
4391 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004392 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004393 Optional arguments:
4394 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004395 retain - Retain only the given values. (intersection of the
4396 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004397 returns:
4398 main.TRUE on success OR
4399 main.FALSE if the set was not changed OR
4400 main.ERROR on error
4401 """
4402 try:
4403 cmdStr = "set-test-remove "
4404 if clear:
4405 cmdStr += "-c " + str( setName )
4406 elif retain:
4407 cmdStr += "-r " + str( setName ) + " " + str( values )
4408 else:
4409 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004410 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004411 if clear:
4412 pattern = "Set " + str( setName ) + " cleared"
4413 if re.search( pattern, output ):
4414 return main.TRUE
4415 elif retain:
4416 positivePattern = str( setName ) + " was pruned to contain " +\
4417 "only elements of set \[(.*)\]"
4418 negativePattern = str( setName ) + " was not changed by " +\
4419 "retaining only elements of the set " +\
4420 "\[(.*)\]"
4421 if re.search( positivePattern, output ):
4422 return main.TRUE
4423 elif re.search( negativePattern, output ):
4424 return main.FALSE
4425 else:
4426 positivePattern = "\[(.*)\] was removed from the set " +\
4427 str( setName )
4428 if ( len( values.split() ) == 1 ):
4429 negativePattern = "\[(.*)\] was not in set " +\
4430 str( setName )
4431 else:
4432 negativePattern = "No element of \[(.*)\] was in set " +\
4433 str( setName )
4434 if re.search( positivePattern, output ):
4435 return main.TRUE
4436 elif re.search( negativePattern, output ):
4437 return main.FALSE
4438 main.log.error( self.name + ": setTestRemove did not" +
4439 " match expected output" )
4440 main.log.debug( self.name + " expected: " + pattern )
4441 main.log.debug( self.name + " actual: " + repr( output ) )
4442 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004443 except TypeError:
4444 main.log.exception( self.name + ": Object not as expected" )
4445 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004446 except Exception:
4447 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004448 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004449
4450 def setTestGet( self, setName, values="" ):
4451 """
4452 CLI command to get the elements in a distributed set.
4453 Required arguments:
4454 setName - The name of the set to remove from.
4455 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004456 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004457 returns:
4458 main.ERROR on error OR
4459 A list of elements in the set if no optional arguments are
4460 supplied OR
4461 A tuple containing the list then:
4462 main.FALSE if the given values are not in the set OR
4463 main.TRUE if the given values are in the set OR
4464 """
4465 try:
4466 values = str( values ).strip()
4467 setName = str( setName ).strip()
4468 length = len( values.split() )
4469 containsCheck = None
4470 # Patterns to match
4471 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004472 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004473 containsTrue = "Set " + setName + " contains the value " + values
4474 containsFalse = "Set " + setName + " did not contain the value " +\
4475 values
4476 containsAllTrue = "Set " + setName + " contains the the subset " +\
4477 setPattern
4478 containsAllFalse = "Set " + setName + " did not contain the the" +\
4479 " subset " + setPattern
4480
4481 cmdStr = "set-test-get "
4482 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004483 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004484 if length == 0:
4485 match = re.search( pattern, output )
4486 else: # if given values
4487 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004488 patternTrue = pattern + "\r\n" + containsTrue
4489 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004490 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004491 patternTrue = pattern + "\r\n" + containsAllTrue
4492 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004493 matchTrue = re.search( patternTrue, output )
4494 matchFalse = re.search( patternFalse, output )
4495 if matchTrue:
4496 containsCheck = main.TRUE
4497 match = matchTrue
4498 elif matchFalse:
4499 containsCheck = main.FALSE
4500 match = matchFalse
4501 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004502 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004503 "expected output" )
4504 main.log.debug( self.name + " expected: " + pattern )
4505 main.log.debug( self.name + " actual: " + repr( output ) )
4506 match = None
4507 if match:
4508 setMatch = match.group( 1 )
4509 if setMatch == '':
4510 setList = []
4511 else:
4512 setList = setMatch.split( ", " )
4513 if length > 0:
4514 return ( setList, containsCheck )
4515 else:
4516 return setList
4517 else: # no match
4518 main.log.error( self.name + ": setTestGet did not" +
4519 " match expected output" )
4520 main.log.debug( self.name + " expected: " + pattern )
4521 main.log.debug( self.name + " actual: " + repr( output ) )
4522 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004523 except TypeError:
4524 main.log.exception( self.name + ": Object not as expected" )
4525 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004526 except Exception:
4527 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004528 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004529
4530 def setTestSize( self, setName ):
4531 """
4532 CLI command to get the elements in a distributed set.
4533 Required arguments:
4534 setName - The name of the set to remove from.
4535 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004536 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004537 None on error
4538 """
4539 try:
4540 # TODO: Should this check against the number of elements returned
4541 # and then return true/false based on that?
4542 setName = str( setName ).strip()
4543 # Patterns to match
4544 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004545 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004546 setPattern
4547 cmdStr = "set-test-get -s "
4548 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004549 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004550 if output:
4551 match = re.search( pattern, output )
4552 if match:
4553 setSize = int( match.group( 1 ) )
4554 setMatch = match.group( 2 )
4555 if len( setMatch.split() ) == setSize:
4556 main.log.info( "The size returned by " + self.name +
4557 " matches the number of elements in " +
4558 "the returned set" )
4559 else:
4560 main.log.error( "The size returned by " + self.name +
4561 " does not match the number of " +
4562 "elements in the returned set." )
4563 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004564 else: # no match
4565 main.log.error( self.name + ": setTestGet did not" +
4566 " match expected output" )
4567 main.log.debug( self.name + " expected: " + pattern )
4568 main.log.debug( self.name + " actual: " + repr( output ) )
4569 return None
Jon Hall390696c2015-05-05 17:13:41 -07004570 except TypeError:
4571 main.log.exception( self.name + ": Object not as expected" )
4572 return None
Jon Hall390696c2015-05-05 17:13:41 -07004573 except Exception:
4574 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004575 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004576
Jon Hall80daded2015-05-27 16:07:00 -07004577 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004578 """
4579 Command to list the various counters in the system.
4580 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004581 if jsonFormat, a string of the json object returned by the cli
4582 command
4583 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004584 None on error
4585 """
Jon Hall390696c2015-05-05 17:13:41 -07004586 try:
Jon Hall390696c2015-05-05 17:13:41 -07004587 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004588 if jsonFormat:
4589 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004590 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004591 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004592 assert "Command not found:" not in output, output
4593 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004594 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004595 return output
Jon Hall390696c2015-05-05 17:13:41 -07004596 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004597 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004598 return None
Jon Hall390696c2015-05-05 17:13:41 -07004599 except TypeError:
4600 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004601 return None
Jon Hall390696c2015-05-05 17:13:41 -07004602 except pexpect.EOF:
4603 main.log.error( self.name + ": EOF exception found" )
4604 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004605 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004606 except Exception:
4607 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004608 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004609
Jon Hall935db192016-04-19 00:22:04 -07004610 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004611 """
Jon Halle1a3b752015-07-22 13:02:46 -07004612 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004613 Required arguments:
4614 counter - The name of the counter to increment.
4615 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004616 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004617 returns:
4618 integer value of the counter or
4619 None on Error
4620 """
4621 try:
4622 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004623 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004624 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004625 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004626 if delta != 1:
4627 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004628 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004629 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004630 match = re.search( pattern, output )
4631 if match:
4632 return int( match.group( 1 ) )
4633 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004634 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004635 " match expected output." )
4636 main.log.debug( self.name + " expected: " + pattern )
4637 main.log.debug( self.name + " actual: " + repr( output ) )
4638 return None
Jon Hall390696c2015-05-05 17:13:41 -07004639 except TypeError:
4640 main.log.exception( self.name + ": Object not as expected" )
4641 return None
Jon Hall390696c2015-05-05 17:13:41 -07004642 except Exception:
4643 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004644 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004645
Jon Hall935db192016-04-19 00:22:04 -07004646 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004647 """
4648 CLI command to get a distributed counter then add a delta to it.
4649 Required arguments:
4650 counter - The name of the counter to increment.
4651 Optional arguments:
4652 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004653 returns:
4654 integer value of the counter or
4655 None on Error
4656 """
4657 try:
4658 counter = str( counter )
4659 delta = int( delta )
4660 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004661 cmdStr += counter
4662 if delta != 1:
4663 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004664 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004665 pattern = counter + " was updated to (-?\d+)"
4666 match = re.search( pattern, output )
4667 if match:
4668 return int( match.group( 1 ) )
4669 else:
4670 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4671 " match expected output." )
4672 main.log.debug( self.name + " expected: " + pattern )
4673 main.log.debug( self.name + " actual: " + repr( output ) )
4674 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004675 except TypeError:
4676 main.log.exception( self.name + ": Object not as expected" )
4677 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004678 except Exception:
4679 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004680 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004681
4682 def valueTestGet( self, valueName ):
4683 """
4684 CLI command to get the value of an atomic value.
4685 Required arguments:
4686 valueName - The name of the value to get.
4687 returns:
4688 string value of the value or
4689 None on Error
4690 """
4691 try:
4692 valueName = str( valueName )
4693 cmdStr = "value-test "
4694 operation = "get"
4695 cmdStr = "value-test {} {}".format( valueName,
4696 operation )
4697 output = self.distPrimitivesSend( cmdStr )
4698 pattern = "(\w+)"
4699 match = re.search( pattern, output )
4700 if match:
4701 return match.group( 1 )
4702 else:
4703 main.log.error( self.name + ": valueTestGet did not" +
4704 " match expected output." )
4705 main.log.debug( self.name + " expected: " + pattern )
4706 main.log.debug( self.name + " actual: " + repr( output ) )
4707 return None
4708 except TypeError:
4709 main.log.exception( self.name + ": Object not as expected" )
4710 return None
4711 except Exception:
4712 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004713 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004714
4715 def valueTestSet( self, valueName, newValue ):
4716 """
4717 CLI command to set the value of an atomic value.
4718 Required arguments:
4719 valueName - The name of the value to set.
4720 newValue - The value to assign to the given value.
4721 returns:
4722 main.TRUE on success or
4723 main.ERROR on Error
4724 """
4725 try:
4726 valueName = str( valueName )
4727 newValue = str( newValue )
4728 operation = "set"
4729 cmdStr = "value-test {} {} {}".format( valueName,
4730 operation,
4731 newValue )
4732 output = self.distPrimitivesSend( cmdStr )
4733 if output is not None:
4734 return main.TRUE
4735 else:
4736 return main.ERROR
4737 except TypeError:
4738 main.log.exception( self.name + ": Object not as expected" )
4739 return main.ERROR
4740 except Exception:
4741 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004742 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004743
4744 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4745 """
4746 CLI command to compareAndSet the value of an atomic value.
4747 Required arguments:
4748 valueName - The name of the value.
4749 oldValue - Compare the current value of the atomic value to this
4750 newValue - If the value equals oldValue, set the value to newValue
4751 returns:
4752 main.TRUE on success or
4753 main.FALSE on failure or
4754 main.ERROR on Error
4755 """
4756 try:
4757 valueName = str( valueName )
4758 oldValue = str( oldValue )
4759 newValue = str( newValue )
4760 operation = "compareAndSet"
4761 cmdStr = "value-test {} {} {} {}".format( valueName,
4762 operation,
4763 oldValue,
4764 newValue )
4765 output = self.distPrimitivesSend( cmdStr )
4766 pattern = "(\w+)"
4767 match = re.search( pattern, output )
4768 if match:
4769 result = match.group( 1 )
4770 if result == "true":
4771 return main.TRUE
4772 elif result == "false":
4773 return main.FALSE
4774 else:
4775 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4776 " match expected output." )
4777 main.log.debug( self.name + " expected: " + pattern )
4778 main.log.debug( self.name + " actual: " + repr( output ) )
4779 return main.ERROR
4780 except TypeError:
4781 main.log.exception( self.name + ": Object not as expected" )
4782 return main.ERROR
4783 except Exception:
4784 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004785 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004786
4787 def valueTestGetAndSet( self, valueName, newValue ):
4788 """
4789 CLI command to getAndSet the value of an atomic value.
4790 Required arguments:
4791 valueName - The name of the value to get.
4792 newValue - The value to assign to the given value
4793 returns:
4794 string value of the value or
4795 None on Error
4796 """
4797 try:
4798 valueName = str( valueName )
4799 cmdStr = "value-test "
4800 operation = "getAndSet"
4801 cmdStr += valueName + " " + operation
4802 cmdStr = "value-test {} {} {}".format( valueName,
4803 operation,
4804 newValue )
4805 output = self.distPrimitivesSend( cmdStr )
4806 pattern = "(\w+)"
4807 match = re.search( pattern, output )
4808 if match:
4809 return match.group( 1 )
4810 else:
4811 main.log.error( self.name + ": valueTestGetAndSet did not" +
4812 " match expected output." )
4813 main.log.debug( self.name + " expected: " + pattern )
4814 main.log.debug( self.name + " actual: " + repr( output ) )
4815 return None
4816 except TypeError:
4817 main.log.exception( self.name + ": Object not as expected" )
4818 return None
4819 except Exception:
4820 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004821 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004822
4823 def valueTestDestroy( self, valueName ):
4824 """
4825 CLI command to destroy an atomic value.
4826 Required arguments:
4827 valueName - The name of the value to destroy.
4828 returns:
4829 main.TRUE on success or
4830 main.ERROR on Error
4831 """
4832 try:
4833 valueName = str( valueName )
4834 cmdStr = "value-test "
4835 operation = "destroy"
4836 cmdStr += valueName + " " + operation
4837 output = self.distPrimitivesSend( cmdStr )
4838 if output is not None:
4839 return main.TRUE
4840 else:
4841 return main.ERROR
4842 except TypeError:
4843 main.log.exception( self.name + ": Object not as expected" )
4844 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004845 except Exception:
4846 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004847 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004848
YPZhangfebf7302016-05-24 16:45:56 -07004849 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004850 """
4851 Description: Execute summary command in onos
4852 Returns: json object ( summary -j ), returns main.FALSE if there is
4853 no output
4854
4855 """
4856 try:
4857 cmdStr = "summary"
4858 if jsonFormat:
4859 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004860 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004861 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004862 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004863 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004864 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004865 if not handle:
4866 main.log.error( self.name + ": There is no output in " +
4867 "summary command" )
4868 return main.FALSE
4869 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004870 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004871 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004872 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004873 except TypeError:
4874 main.log.exception( self.name + ": Object not as expected" )
4875 return None
4876 except pexpect.EOF:
4877 main.log.error( self.name + ": EOF exception found" )
4878 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004879 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004880 except Exception:
4881 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004882 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004883
Jon Hall935db192016-04-19 00:22:04 -07004884 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004885 """
4886 CLI command to get the value of a key in a consistent map using
4887 transactions. This a test function and can only get keys from the
4888 test map hard coded into the cli command
4889 Required arguments:
4890 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004891 returns:
4892 The string value of the key or
4893 None on Error
4894 """
4895 try:
4896 keyName = str( keyName )
4897 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004898 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004899 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004900 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4901 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004902 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004903 return None
4904 else:
4905 match = re.search( pattern, output )
4906 if match:
4907 return match.groupdict()[ 'value' ]
4908 else:
4909 main.log.error( self.name + ": transactionlMapGet did not" +
4910 " match expected output." )
4911 main.log.debug( self.name + " expected: " + pattern )
4912 main.log.debug( self.name + " actual: " + repr( output ) )
4913 return None
4914 except TypeError:
4915 main.log.exception( self.name + ": Object not as expected" )
4916 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004917 except Exception:
4918 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004919 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004920
Jon Hall935db192016-04-19 00:22:04 -07004921 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004922 """
4923 CLI command to put a value into 'numKeys' number of keys in a
4924 consistent map using transactions. This a test function and can only
4925 put into keys named 'Key#' of the test map hard coded into the cli command
4926 Required arguments:
4927 numKeys - Number of keys to add the value to
4928 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004929 returns:
4930 A dictionary whose keys are the name of the keys put into the map
4931 and the values of the keys are dictionaries whose key-values are
4932 'value': value put into map and optionaly
4933 'oldValue': Previous value in the key or
4934 None on Error
4935
4936 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004937 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4938 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004939 """
4940 try:
4941 numKeys = str( numKeys )
4942 value = str( value )
4943 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004944 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004945 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004946 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4947 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4948 results = {}
4949 for line in output.splitlines():
4950 new = re.search( newPattern, line )
4951 updated = re.search( updatedPattern, line )
4952 if new:
4953 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4954 elif updated:
4955 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004956 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004957 else:
4958 main.log.error( self.name + ": transactionlMapGet did not" +
4959 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004960 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4961 newPattern,
4962 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004963 main.log.debug( self.name + " actual: " + repr( output ) )
4964 return results
Jon Hall0e240372018-05-02 11:21:57 -07004965 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004966 main.log.exception( self.name + ": Object not as expected" )
4967 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004968 except Exception:
4969 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004970 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004971
acsmarsdaea66c2015-09-03 11:44:06 -07004972 def maps( self, jsonFormat=True ):
4973 """
4974 Description: Returns result of onos:maps
4975 Optional:
4976 * jsonFormat: enable json formatting of output
4977 """
4978 try:
4979 cmdStr = "maps"
4980 if jsonFormat:
4981 cmdStr += " -j"
4982 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004983 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004984 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004985 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004986 except AssertionError:
4987 main.log.exception( "" )
4988 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004989 except TypeError:
4990 main.log.exception( self.name + ": Object not as expected" )
4991 return None
4992 except pexpect.EOF:
4993 main.log.error( self.name + ": EOF exception found" )
4994 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004995 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004996 except Exception:
4997 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004998 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004999
5000 def getSwController( self, uri, jsonFormat=True ):
5001 """
5002 Descrition: Gets the controller information from the device
5003 """
5004 try:
5005 cmd = "device-controllers "
5006 if jsonFormat:
5007 cmd += "-j "
5008 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07005009 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005010 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005011 return response
Jon Hallc6793552016-01-19 14:18:37 -08005012 except AssertionError:
5013 main.log.exception( "" )
5014 return None
GlennRC050596c2015-11-18 17:06:41 -08005015 except TypeError:
5016 main.log.exception( self.name + ": Object not as expected" )
5017 return None
5018 except pexpect.EOF:
5019 main.log.error( self.name + ": EOF exception found" )
5020 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005021 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005022 except Exception:
5023 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005024 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005025
5026 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
5027 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005028 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08005029
5030 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005031 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08005032 ip - String or List: The ip address of the controller.
5033 This parameter can be formed in a couple of different ways.
5034 VALID:
5035 10.0.0.1 - just the ip address
5036 tcp:10.0.0.1 - the protocol and the ip address
5037 tcp:10.0.0.1:6653 - the protocol and port can be specified,
5038 so that you can add controllers with different
5039 protocols and ports
5040 INVALID:
5041 10.0.0.1:6653 - this is not supported by ONOS
5042
5043 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
5044 port - The port number.
5045 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
5046
5047 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
5048 """
5049 try:
5050 cmd = "device-setcontrollers"
5051
5052 if jsonFormat:
5053 cmd += " -j"
5054 cmd += " " + uri
5055 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005056 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08005057 for item in ip:
5058 if ":" in item:
5059 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005060 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08005061 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005062 elif "." in sitem[ 1 ]:
5063 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08005064 else:
5065 main.log.error( "Malformed entry: " + item )
5066 raise TypeError
5067 else:
5068 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08005069 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07005070 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005071 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005072 if "Error" in response:
5073 main.log.error( response )
5074 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005075 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005076 except AssertionError:
5077 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005078 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005079 except TypeError:
5080 main.log.exception( self.name + ": Object not as expected" )
5081 return main.FALSE
5082 except pexpect.EOF:
5083 main.log.error( self.name + ": EOF exception found" )
5084 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005085 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005086 except Exception:
5087 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005088 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005089
5090 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005091 '''
GlennRC20fc6522015-12-23 23:26:57 -08005092 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005093 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005094 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005095 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005096 Returns:
5097 Returns main.FALSE if an exception is thrown or an error is present
5098 in the response. Otherwise, returns main.TRUE.
5099 NOTE:
5100 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005101 '''
GlennRC20fc6522015-12-23 23:26:57 -08005102 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005103 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005104 deviceStr = device
5105 device = []
5106 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005107
5108 for d in device:
5109 time.sleep( 1 )
5110 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005111 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005112 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005113 if "Error" in response:
5114 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5115 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005116 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005117 except AssertionError:
5118 main.log.exception( "" )
5119 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005120 except TypeError:
5121 main.log.exception( self.name + ": Object not as expected" )
5122 return main.FALSE
5123 except pexpect.EOF:
5124 main.log.error( self.name + ": EOF exception found" )
5125 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005126 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005127 except Exception:
5128 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005129 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005130
5131 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005132 '''
GlennRC20fc6522015-12-23 23:26:57 -08005133 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005134 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005135 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005136 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005137 Returns:
5138 Returns main.FALSE if an exception is thrown or an error is present
5139 in the response. Otherwise, returns main.TRUE.
5140 NOTE:
5141 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005142 '''
GlennRC20fc6522015-12-23 23:26:57 -08005143 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005144 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005145 host = list( host )
5146
5147 for h in host:
5148 time.sleep( 1 )
5149 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005150 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005151 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005152 if "Error" in response:
5153 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5154 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005155 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005156 except AssertionError:
5157 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005158 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005159 except TypeError:
5160 main.log.exception( self.name + ": Object not as expected" )
5161 return main.FALSE
5162 except pexpect.EOF:
5163 main.log.error( self.name + ": EOF exception found" )
5164 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005165 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005166 except Exception:
5167 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005168 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005169
YPZhangfebf7302016-05-24 16:45:56 -07005170 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005171 '''
GlennRCed771242016-01-13 17:02:47 -08005172 Description:
5173 Bring link down or up in the null-provider.
5174 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005175 begin - (string) One end of a device or switch.
5176 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005177 returns:
5178 main.TRUE if no exceptions were thrown and no Errors are
5179 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005180 '''
GlennRCed771242016-01-13 17:02:47 -08005181 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005182 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005183 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005184 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005185 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005186 if "Error" in response or "Failure" in response:
5187 main.log.error( response )
5188 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005189 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005190 except AssertionError:
5191 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005192 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005193 except TypeError:
5194 main.log.exception( self.name + ": Object not as expected" )
5195 return main.FALSE
5196 except pexpect.EOF:
5197 main.log.error( self.name + ": EOF exception found" )
5198 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005199 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005200 except Exception:
5201 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005202 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005203
Jon Hall2c8959e2016-12-16 12:17:34 -08005204 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005205 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005206 Description:
5207 Changes the state of port in an OF switch by means of the
5208 PORTSTATUS OF messages.
5209 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005210 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5211 port - (string) target port in the device. Ex: '2'
5212 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005213 returns:
5214 main.TRUE if no exceptions were thrown and no Errors are
5215 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005216 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005217 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005218 state = state.lower()
5219 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005220 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005221 response = self.sendline( cmd, showResponse=True )
5222 assert response is not None, "Error in sendline"
5223 assert "Command not found:" not in response, response
5224 if "Error" in response or "Failure" in response:
5225 main.log.error( response )
5226 return main.FALSE
5227 return main.TRUE
5228 except AssertionError:
5229 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005230 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005231 except TypeError:
5232 main.log.exception( self.name + ": Object not as expected" )
5233 return main.FALSE
5234 except pexpect.EOF:
5235 main.log.error( self.name + ": EOF exception found" )
5236 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005237 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005238 except Exception:
5239 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005240 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005241
5242 def logSet( self, level="INFO", app="org.onosproject" ):
5243 """
5244 Set the logging level to lvl for a specific app
5245 returns main.TRUE on success
5246 returns main.FALSE if Error occurred
5247 if noExit is True, TestON will not exit, but clean up
5248 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5249 Level defaults to INFO
5250 """
5251 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005252 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -08005253 self.handle.expect( self.karafPrompt )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005254
5255 response = self.handle.before
5256 if re.search( "Error", response ):
5257 return main.FALSE
5258 return main.TRUE
5259 except pexpect.TIMEOUT:
5260 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005261 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005262 except pexpect.EOF:
5263 main.log.error( self.name + ": EOF exception found" )
5264 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005265 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005266 except Exception:
5267 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005268 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005269
5270 def getGraphDict( self, timeout=60, includeHost=False ):
5271 """
5272 Return a dictionary which describes the latest network topology data as a
5273 graph.
5274 An example of the dictionary:
5275 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5276 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5277 Each vertex should at least have an 'edges' attribute which describes the
5278 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005279 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005280 list of attributes.
5281 An example of the edges dictionary:
5282 'edges': { vertex2: { 'port': ..., 'weight': ... },
5283 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005284 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005285 in topology data.
5286 """
5287 graphDict = {}
5288 try:
5289 links = self.links()
5290 links = json.loads( links )
5291 devices = self.devices()
5292 devices = json.loads( devices )
5293 idToDevice = {}
5294 for device in devices:
5295 idToDevice[ device[ 'id' ] ] = device
5296 if includeHost:
5297 hosts = self.hosts()
5298 # FIXME: support 'includeHost' argument
5299 for link in links:
5300 nodeA = link[ 'src' ][ 'device' ]
5301 nodeB = link[ 'dst' ][ 'device' ]
5302 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005303 if nodeA not in graphDict.keys():
5304 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005305 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005306 'type': idToDevice[ nodeA ][ 'type' ],
5307 'available': idToDevice[ nodeA ][ 'available' ],
5308 'role': idToDevice[ nodeA ][ 'role' ],
5309 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5310 'hw': idToDevice[ nodeA ][ 'hw' ],
5311 'sw': idToDevice[ nodeA ][ 'sw' ],
5312 'serial': idToDevice[ nodeA ][ 'serial' ],
5313 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005314 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005315 else:
5316 # Assert nodeB is not connected to any current links of nodeA
5317 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005318 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5319 'type': link[ 'type' ],
5320 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005321 return graphDict
5322 except ( TypeError, ValueError ):
5323 main.log.exception( self.name + ": Object not as expected" )
5324 return None
5325 except KeyError:
5326 main.log.exception( self.name + ": KeyError exception found" )
5327 return None
5328 except AssertionError:
5329 main.log.exception( self.name + ": AssertionError exception found" )
5330 return None
5331 except pexpect.EOF:
5332 main.log.error( self.name + ": EOF exception found" )
5333 main.log.error( self.name + ": " + self.handle.before )
5334 return None
5335 except Exception:
5336 main.log.exception( self.name + ": Uncaught exception!" )
5337 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005338
5339 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005340 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005341 Send command to check intent-perf summary
5342 Returns: dictionary for intent-perf summary
5343 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005344 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005345 cmd = "intent-perf -s"
5346 respDic = {}
5347 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005348 assert resp is not None, "Error in sendline"
5349 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005350 try:
5351 # Generate the dictionary to return
5352 for l in resp.split( "\n" ):
5353 # Delete any white space in line
5354 temp = re.sub( r'\s+', '', l )
5355 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005356 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005357
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005358 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005359 main.log.exception( self.name + ": Object not as expected" )
5360 return None
5361 except KeyError:
5362 main.log.exception( self.name + ": KeyError exception found" )
5363 return None
5364 except AssertionError:
5365 main.log.exception( self.name + ": AssertionError exception found" )
5366 return None
5367 except pexpect.EOF:
5368 main.log.error( self.name + ": EOF exception found" )
5369 main.log.error( self.name + ": " + self.handle.before )
5370 return None
5371 except Exception:
5372 main.log.exception( self.name + ": Uncaught exception!" )
5373 return None
5374 return respDic
5375
Chiyu Chengec63bde2016-11-17 18:11:36 -08005376 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005377 """
5378 Searches the latest ONOS log file for the given search term and
5379 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005380
chengchiyu08303a02016-09-08 17:40:26 -07005381 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005382 searchTerm:
5383 The string to grep from the ONOS log.
5384 startLine:
5385 The term that decides which line is the start to search the searchTerm in
5386 the karaf log. For now, startTerm only works in 'first' mode.
5387 logNum:
5388 In some extreme cases, one karaf log is not big enough to contain all the
5389 information.Because of this, search mutiply logs is necessary to capture
5390 the right result. logNum is the number of karaf logs that we need to search
5391 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005392 mode:
5393 all: return all the strings that contain the search term
5394 last: return the last string that contains the search term
5395 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005396 num: return the number of times that the searchTerm appears in the log
5397 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005398 """
5399 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005400 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005401 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005402 logPath = '/opt/onos/log/karaf.log.'
5403 logPaths = '/opt/onos/log/karaf.log'
5404 for i in range( 1, logNum ):
5405 logPaths = logPath + str( i ) + " " + logPaths
5406 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005407 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005408 # 100000000 is just a extreme large number to make sure this function can
5409 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005410 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005411 if mode == 'all':
5412 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005413 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005414 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005415 elif mode == 'first':
5416 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5417 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005418 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005419 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005420 return num
You Wang6d301d42017-04-21 10:49:33 -07005421 elif mode == 'total':
Jon Halld5a94fb2018-11-13 14:32:23 -08005422 totalLines = self.lineCount( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005423 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005424 else:
5425 main.log.error( self.name + " unsupported mode" )
5426 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005427 before = self.sendline( cmd )
5428 before = before.splitlines()
5429 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005430 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005431 return returnLines
5432 except AssertionError:
5433 main.log.error( self.name + " searchTerm is not string type" )
5434 return None
5435 except pexpect.EOF:
5436 main.log.error( self.name + ": EOF exception found" )
5437 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005438 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005439 except pexpect.TIMEOUT:
5440 main.log.error( self.name + ": TIMEOUT exception found" )
5441 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005442 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005443 except Exception:
5444 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005445 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005446
5447 def vplsShow( self, jsonFormat=True ):
5448 """
5449 Description: Returns result of onos:vpls show, which should list the
5450 configured VPLS networks and the assigned interfaces.
5451 Optional:
5452 * jsonFormat: enable json formatting of output
5453 Returns:
5454 The output of the command or None on error.
5455 """
5456 try:
5457 cmdStr = "vpls show"
5458 if jsonFormat:
5459 raise NotImplementedError
5460 cmdStr += " -j"
5461 handle = self.sendline( cmdStr )
5462 assert handle is not None, "Error in sendline"
5463 assert "Command not found:" not in handle, handle
5464 return handle
5465 except AssertionError:
5466 main.log.exception( "" )
5467 return None
5468 except TypeError:
5469 main.log.exception( self.name + ": Object not as expected" )
5470 return None
5471 except pexpect.EOF:
5472 main.log.error( self.name + ": EOF exception found" )
5473 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005474 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005475 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005476 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005477 return None
5478 except Exception:
5479 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005480 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005481
5482 def parseVplsShow( self ):
5483 """
5484 Parse the cli output of 'vpls show' into json output. This is required
5485 as there is currently no json output available.
5486 """
5487 try:
5488 output = []
5489 raw = self.vplsShow( jsonFormat=False )
5490 namePat = "VPLS name: (?P<name>\w+)"
5491 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5492 encapPat = "Encapsulation: (?P<encap>\w+)"
5493 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5494 mIter = re.finditer( pattern, raw )
5495 for match in mIter:
5496 item = {}
5497 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005498 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005499 if ifaces == [ "" ]:
5500 ifaces = []
5501 item[ 'interfaces' ] = ifaces
5502 encap = match.group( 'encap' )
5503 if encap != 'NONE':
5504 item[ 'encapsulation' ] = encap.lower()
5505 output.append( item )
5506 return output
5507 except Exception:
5508 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005509 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005510
5511 def vplsList( self, jsonFormat=True ):
5512 """
5513 Description: Returns result of onos:vpls list, which should list the
5514 configured VPLS networks.
5515 Optional:
5516 * jsonFormat: enable json formatting of output
5517 """
5518 try:
5519 cmdStr = "vpls list"
5520 if jsonFormat:
5521 raise NotImplementedError
5522 cmdStr += " -j"
5523 handle = self.sendline( cmdStr )
5524 assert handle is not None, "Error in sendline"
5525 assert "Command not found:" not in handle, handle
5526 return handle
5527 except AssertionError:
5528 main.log.exception( "" )
5529 return None
5530 except TypeError:
5531 main.log.exception( self.name + ": Object not as expected" )
5532 return None
5533 except pexpect.EOF:
5534 main.log.error( self.name + ": EOF exception found" )
5535 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005536 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005537 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005538 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005539 return None
5540 except Exception:
5541 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005542 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005543
5544 def vplsCreate( self, network ):
5545 """
5546 CLI command to create a new VPLS network.
5547 Required arguments:
5548 network - String name of the network to create.
5549 returns:
5550 main.TRUE on success and main.FALSE on failure
5551 """
5552 try:
5553 network = str( network )
5554 cmdStr = "vpls create "
5555 cmdStr += network
5556 output = self.sendline( cmdStr )
5557 assert output is not None, "Error in sendline"
5558 assert "Command not found:" not in output, output
5559 assert "Error executing command" not in output, output
5560 assert "VPLS already exists:" not in output, output
5561 return main.TRUE
5562 except AssertionError:
5563 main.log.exception( "" )
5564 return main.FALSE
5565 except TypeError:
5566 main.log.exception( self.name + ": Object not as expected" )
5567 return main.FALSE
5568 except pexpect.EOF:
5569 main.log.error( self.name + ": EOF exception found" )
5570 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005571 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005572 except Exception:
5573 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005574 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005575
5576 def vplsDelete( self, network ):
5577 """
5578 CLI command to delete a VPLS network.
5579 Required arguments:
5580 network - Name of the network to delete.
5581 returns:
5582 main.TRUE on success and main.FALSE on failure
5583 """
5584 try:
5585 network = str( network )
5586 cmdStr = "vpls delete "
5587 cmdStr += network
5588 output = self.sendline( cmdStr )
5589 assert output is not None, "Error in sendline"
5590 assert "Command not found:" not in output, output
5591 assert "Error executing command" not in output, output
5592 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005593 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005594 return main.TRUE
5595 except AssertionError:
5596 main.log.exception( "" )
5597 return main.FALSE
5598 except TypeError:
5599 main.log.exception( self.name + ": Object not as expected" )
5600 return main.FALSE
5601 except pexpect.EOF:
5602 main.log.error( self.name + ": EOF exception found" )
5603 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005604 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005605 except Exception:
5606 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005607 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005608
5609 def vplsAddIface( self, network, iface ):
5610 """
5611 CLI command to add an interface to a VPLS network.
5612 Required arguments:
5613 network - Name of the network to add the interface to.
5614 iface - The ONOS name for an interface.
5615 returns:
5616 main.TRUE on success and main.FALSE on failure
5617 """
5618 try:
5619 network = str( network )
5620 iface = str( iface )
5621 cmdStr = "vpls add-if "
5622 cmdStr += network + " " + iface
5623 output = self.sendline( cmdStr )
5624 assert output is not None, "Error in sendline"
5625 assert "Command not found:" not in output, output
5626 assert "Error executing command" not in output, output
5627 assert "already associated to network" not in output, output
5628 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005629 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005630 return main.TRUE
5631 except AssertionError:
5632 main.log.exception( "" )
5633 return main.FALSE
5634 except TypeError:
5635 main.log.exception( self.name + ": Object not as expected" )
5636 return main.FALSE
5637 except pexpect.EOF:
5638 main.log.error( self.name + ": EOF exception found" )
5639 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005640 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005641 except Exception:
5642 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005643 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005644
5645 def vplsRemIface( self, network, iface ):
5646 """
5647 CLI command to remove an interface from a VPLS network.
5648 Required arguments:
5649 network - Name of the network to remove the interface from.
5650 iface - Name of the interface to remove.
5651 returns:
5652 main.TRUE on success and main.FALSE on failure
5653 """
5654 try:
5655 iface = str( iface )
5656 cmdStr = "vpls rem-if "
5657 cmdStr += network + " " + iface
5658 output = self.sendline( cmdStr )
5659 assert output is not None, "Error in sendline"
5660 assert "Command not found:" not in output, output
5661 assert "Error executing command" not in output, output
5662 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005663 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005664 return main.TRUE
5665 except AssertionError:
5666 main.log.exception( "" )
5667 return main.FALSE
5668 except TypeError:
5669 main.log.exception( self.name + ": Object not as expected" )
5670 return main.FALSE
5671 except pexpect.EOF:
5672 main.log.error( self.name + ": EOF exception found" )
5673 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005674 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005675 except Exception:
5676 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005677 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005678
5679 def vplsClean( self ):
5680 """
5681 Description: Clears the VPLS app configuration.
5682 Returns: main.TRUE on success and main.FALSE on failure
5683 """
5684 try:
5685 cmdStr = "vpls clean"
5686 handle = self.sendline( cmdStr )
5687 assert handle is not None, "Error in sendline"
5688 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005689 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005690 return handle
5691 except AssertionError:
5692 main.log.exception( "" )
5693 return main.FALSE
5694 except TypeError:
5695 main.log.exception( self.name + ": Object not as expected" )
5696 return main.FALSE
5697 except pexpect.EOF:
5698 main.log.error( self.name + ": EOF exception found" )
5699 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005700 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005701 except Exception:
5702 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005703 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005704
5705 def vplsSetEncap( self, network, encapType ):
5706 """
5707 CLI command to add an interface to a VPLS network.
5708 Required arguments:
5709 network - Name of the network to create.
5710 encapType - Type of encapsulation.
5711 returns:
5712 main.TRUE on success and main.FALSE on failure
5713 """
5714 try:
5715 network = str( network )
5716 encapType = str( encapType ).upper()
5717 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5718 cmdStr = "vpls set-encap "
5719 cmdStr += network + " " + encapType
5720 output = self.sendline( cmdStr )
5721 assert output is not None, "Error in sendline"
5722 assert "Command not found:" not in output, output
5723 assert "Error executing command" not in output, output
5724 assert "already associated to network" not in output, output
5725 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005726 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005727 return main.TRUE
5728 except AssertionError:
5729 main.log.exception( "" )
5730 return main.FALSE
5731 except TypeError:
5732 main.log.exception( self.name + ": Object not as expected" )
5733 return main.FALSE
5734 except pexpect.EOF:
5735 main.log.error( self.name + ": EOF exception found" )
5736 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005737 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005738 except Exception:
5739 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005740 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005741
5742 def interfaces( self, jsonFormat=True ):
5743 """
5744 Description: Returns result of interfaces command.
5745 Optional:
5746 * jsonFormat: enable json formatting of output
5747 Returns:
5748 The output of the command or None on error.
5749 """
5750 try:
5751 cmdStr = "interfaces"
5752 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005753 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005754 cmdStr += " -j"
5755 handle = self.sendline( cmdStr )
5756 assert handle is not None, "Error in sendline"
5757 assert "Command not found:" not in handle, handle
5758 return handle
5759 except AssertionError:
5760 main.log.exception( "" )
5761 return None
5762 except TypeError:
5763 main.log.exception( self.name + ": Object not as expected" )
5764 return None
5765 except pexpect.EOF:
5766 main.log.error( self.name + ": EOF exception found" )
5767 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005768 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005769 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005770 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005771 return None
5772 except Exception:
5773 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005774 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005775
5776 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005777 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005778 Get the timestamp of searchTerm from karaf log.
5779
5780 Arguments:
5781 splitTerm_before and splitTerm_after:
5782
5783 The terms that split the string that contains the timeStamp of
5784 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5785 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5786 and the splitTerm_after is "x"
5787
5788 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005789 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005790 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005791 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005792 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005793 return main.ERROR
5794 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005795 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005796 main.log.warn( "Captured timestamp string is empty" )
5797 return main.ERROR
5798 lines = lines[ 0 ]
5799 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005800 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005801 # get the target value
5802 line = lines.split( splitTerm_before )
5803 key = line[ 1 ].split( splitTerm_after )
5804 return int( key[ 0 ] )
5805 except IndexError:
5806 main.log.warn( "Index Error!" )
5807 return main.ERROR
5808 except AssertionError:
5809 main.log.warn( "Search Term Not Found " )
5810 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005811
5812 def workQueueAdd( self, queueName, value ):
5813 """
5814 CLI command to add a string to the specified Work Queue.
5815 This function uses the distributed primitives test app, which
5816 gives some cli access to distributed primitives for testing
5817 purposes only.
5818
5819 Required arguments:
5820 queueName - The name of the queue to add to
5821 value - The value to add to the queue
5822 returns:
5823 main.TRUE on success, main.FALSE on failure and
5824 main.ERROR on error.
5825 """
5826 try:
5827 queueName = str( queueName )
5828 value = str( value )
5829 prefix = "work-queue-test"
5830 operation = "add"
5831 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5832 output = self.distPrimitivesSend( cmdStr )
5833 if "Invalid operation name" in output:
5834 main.log.warn( output )
5835 return main.ERROR
5836 elif "Done" in output:
5837 return main.TRUE
5838 except TypeError:
5839 main.log.exception( self.name + ": Object not as expected" )
5840 return main.ERROR
5841 except Exception:
5842 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005843 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005844
5845 def workQueueAddMultiple( self, queueName, value1, value2 ):
5846 """
5847 CLI command to add two strings to the specified Work Queue.
5848 This function uses the distributed primitives test app, which
5849 gives some cli access to distributed primitives for testing
5850 purposes only.
5851
5852 Required arguments:
5853 queueName - The name of the queue to add to
5854 value1 - The first value to add to the queue
5855 value2 - The second value to add to the queue
5856 returns:
5857 main.TRUE on success, main.FALSE on failure and
5858 main.ERROR on error.
5859 """
5860 try:
5861 queueName = str( queueName )
5862 value1 = str( value1 )
5863 value2 = str( value2 )
5864 prefix = "work-queue-test"
5865 operation = "addMultiple"
5866 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5867 output = self.distPrimitivesSend( cmdStr )
5868 if "Invalid operation name" in output:
5869 main.log.warn( output )
5870 return main.ERROR
5871 elif "Done" in output:
5872 return main.TRUE
5873 except TypeError:
5874 main.log.exception( self.name + ": Object not as expected" )
5875 return main.ERROR
5876 except Exception:
5877 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005878 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005879
5880 def workQueueTakeAndComplete( self, queueName, number=1 ):
5881 """
5882 CLI command to take a value from the specified Work Queue and compelte it.
5883 This function uses the distributed primitives test app, which
5884 gives some cli access to distributed primitives for testing
5885 purposes only.
5886
5887 Required arguments:
5888 queueName - The name of the queue to add to
5889 number - The number of items to take and complete
5890 returns:
5891 main.TRUE on success, main.FALSE on failure and
5892 main.ERROR on error.
5893 """
5894 try:
5895 queueName = str( queueName )
5896 number = str( int( number ) )
5897 prefix = "work-queue-test"
5898 operation = "takeAndComplete"
5899 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5900 output = self.distPrimitivesSend( cmdStr )
5901 if "Invalid operation name" in output:
5902 main.log.warn( output )
5903 return main.ERROR
5904 elif "Done" in output:
5905 return main.TRUE
5906 except TypeError:
5907 main.log.exception( self.name + ": Object not as expected" )
5908 return main.ERROR
5909 except Exception:
5910 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005911 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005912
5913 def workQueueDestroy( self, queueName ):
5914 """
5915 CLI command to destroy the specified Work Queue.
5916 This function uses the distributed primitives test app, which
5917 gives some cli access to distributed primitives for testing
5918 purposes only.
5919
5920 Required arguments:
5921 queueName - The name of the queue to add to
5922 returns:
5923 main.TRUE on success, main.FALSE on failure and
5924 main.ERROR on error.
5925 """
5926 try:
5927 queueName = str( queueName )
5928 prefix = "work-queue-test"
5929 operation = "destroy"
5930 cmdStr = " ".join( [ prefix, queueName, operation ] )
5931 output = self.distPrimitivesSend( cmdStr )
5932 if "Invalid operation name" in output:
5933 main.log.warn( output )
5934 return main.ERROR
5935 return main.TRUE
5936 except TypeError:
5937 main.log.exception( self.name + ": Object not as expected" )
5938 return main.ERROR
5939 except Exception:
5940 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005941 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005942
5943 def workQueueTotalPending( self, queueName ):
5944 """
5945 CLI command to get the Total Pending items of the specified Work Queue.
5946 This function uses the distributed primitives test app, which
5947 gives some cli access to distributed primitives for testing
5948 purposes only.
5949
5950 Required arguments:
5951 queueName - The name of the queue to add to
5952 returns:
5953 The number of Pending items in the specified work queue or
5954 None on error
5955 """
5956 try:
5957 queueName = str( queueName )
5958 prefix = "work-queue-test"
5959 operation = "totalPending"
5960 cmdStr = " ".join( [ prefix, queueName, operation ] )
5961 output = self.distPrimitivesSend( cmdStr )
5962 pattern = r'\d+'
5963 if "Invalid operation name" in output:
5964 main.log.warn( output )
5965 return None
5966 else:
5967 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005968 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005969 except ( AttributeError, TypeError ):
5970 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5971 return None
5972 except Exception:
5973 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005974 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005975
5976 def workQueueTotalCompleted( self, queueName ):
5977 """
5978 CLI command to get the Total Completed items of the specified Work Queue.
5979 This function uses the distributed primitives test app, which
5980 gives some cli access to distributed primitives for testing
5981 purposes only.
5982
5983 Required arguments:
5984 queueName - The name of the queue to add to
5985 returns:
5986 The number of complete items in the specified work queue or
5987 None on error
5988 """
5989 try:
5990 queueName = str( queueName )
5991 prefix = "work-queue-test"
5992 operation = "totalCompleted"
5993 cmdStr = " ".join( [ prefix, queueName, operation ] )
5994 output = self.distPrimitivesSend( cmdStr )
5995 pattern = r'\d+'
5996 if "Invalid operation name" in output:
5997 main.log.warn( output )
5998 return None
5999 else:
6000 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006001 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006002 except ( AttributeError, TypeError ):
6003 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6004 return None
6005 except Exception:
6006 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006007 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07006008
6009 def workQueueTotalInProgress( self, queueName ):
6010 """
6011 CLI command to get the Total In Progress items of the specified Work Queue.
6012 This function uses the distributed primitives test app, which
6013 gives some cli access to distributed primitives for testing
6014 purposes only.
6015
6016 Required arguments:
6017 queueName - The name of the queue to add to
6018 returns:
6019 The number of In Progress items in the specified work queue or
6020 None on error
6021 """
6022 try:
6023 queueName = str( queueName )
6024 prefix = "work-queue-test"
6025 operation = "totalInProgress"
6026 cmdStr = " ".join( [ prefix, queueName, operation ] )
6027 output = self.distPrimitivesSend( cmdStr )
6028 pattern = r'\d+'
6029 if "Invalid operation name" in output:
6030 main.log.warn( output )
6031 return None
6032 else:
6033 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006034 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006035 except ( AttributeError, TypeError ):
6036 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6037 return None
6038 except Exception:
6039 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006040 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00006041
6042 def events( self, args='-a' ):
6043 """
6044 Description: Returns events -a command output
6045 Optional:
6046 add other arguments
6047 """
6048 try:
6049 cmdStr = "events"
6050 if args:
6051 cmdStr += " " + args
6052 handle = self.sendline( cmdStr )
6053 assert handle is not None, "Error in sendline"
6054 assert "Command not found:" not in handle, handle
6055 return handle
6056 except AssertionError:
6057 main.log.exception( "" )
6058 return None
6059 except TypeError:
6060 main.log.exception( self.name + ": Object not as expected" )
6061 return None
6062 except pexpect.EOF:
6063 main.log.error( self.name + ": EOF exception found" )
6064 main.log.error( self.name + ": " + self.handle.before )
6065 main.cleanAndExit()
6066 except Exception:
6067 main.log.exception( self.name + ": Uncaught exception!" )
6068 main.cleanAndExit()
6069
6070 def getMaster( self, deviceID ):
6071 """
6072 Description: Obtains current master using "roles" command for a specific deviceID
6073 """
6074 try:
6075 return str( self.getRole( deviceID )[ 'master' ] )
6076 except AssertionError:
6077 main.log.exception( "" )
6078 return None
6079 except TypeError:
6080 main.log.exception( self.name + ": Object not as expected" )
6081 return None
6082 except pexpect.EOF:
6083 main.log.error( self.name + ": EOF exception found" )
6084 main.log.error( self.name + ": " + self.handle.before )
6085 main.cleanAndExit()
6086 except Exception:
6087 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006088 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006089
6090 def issu( self ):
6091 """
6092 Short summary of In-Service Software Upgrade status
6093
6094 Returns the output of the cli command or None on Error
6095 """
6096 try:
6097 cmdStr = "issu"
6098 handle = self.sendline( cmdStr )
6099 assert handle is not None, "Error in sendline"
6100 assert "Command not found:" not in handle, handle
6101 assert "Unsupported command:" not in handle, handle
6102 return handle
6103 except AssertionError:
6104 main.log.exception( "" )
6105 return None
6106 except TypeError:
6107 main.log.exception( self.name + ": Object not as expected" )
6108 return None
6109 except pexpect.EOF:
6110 main.log.error( self.name + ": EOF exception found" )
6111 main.log.error( self.name + ": " + self.handle.before )
6112 main.cleanAndExit()
6113 except Exception:
6114 main.log.exception( self.name + ": Uncaught exception!" )
6115 main.cleanAndExit()
6116
6117 def issuInit( self ):
6118 """
6119 Initiates an In-Service Software Upgrade
6120
6121 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6122 """
6123 try:
6124 cmdStr = "issu init"
6125 handle = self.sendline( cmdStr )
6126 assert handle is not None, "Error in sendline"
6127 assert "Command not found:" not in handle, handle
6128 assert "Unsupported command:" not in handle, handle
6129 if "Initialized" in handle:
6130 return main.TRUE
6131 else:
6132 return main.FALSE
6133 except AssertionError:
6134 main.log.exception( "" )
6135 return main.ERROR
6136 except TypeError:
6137 main.log.exception( self.name + ": Object not as expected" )
6138 return main.ERROR
6139 except pexpect.EOF:
6140 main.log.error( self.name + ": EOF exception found" )
6141 main.log.error( self.name + ": " + self.handle.before )
6142 main.cleanAndExit()
6143 except Exception:
6144 main.log.exception( self.name + ": Uncaught exception!" )
6145 main.cleanAndExit()
6146
6147 def issuUpgrade( self ):
6148 """
6149 Transitions stores to upgraded nodes
6150
6151 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6152 """
6153 try:
6154 cmdStr = "issu upgrade"
6155 handle = self.sendline( cmdStr )
6156 assert handle is not None, "Error in sendline"
6157 assert "Command not found:" not in handle, handle
6158 assert "Unsupported command:" not in handle, handle
6159 if "Upgraded" in handle:
6160 return main.TRUE
6161 else:
6162 return main.FALSE
6163 except AssertionError:
6164 main.log.exception( "" )
6165 return main.ERROR
6166 except TypeError:
6167 main.log.exception( self.name + ": Object not as expected" )
6168 return main.ERROR
6169 except pexpect.EOF:
6170 main.log.error( self.name + ": EOF exception found" )
6171 main.log.error( self.name + ": " + self.handle.before )
6172 main.cleanAndExit()
6173 except Exception:
6174 main.log.exception( self.name + ": Uncaught exception!" )
6175 main.cleanAndExit()
6176
6177 def issuCommit( self ):
6178 """
6179 Finalizes an In-Service Software Upgrade
6180
6181 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6182 """
6183 try:
6184 cmdStr = "issu commit"
6185 handle = self.sendline( cmdStr )
6186 assert handle is not None, "Error in sendline"
6187 assert "Command not found:" not in handle, handle
6188 assert "Unsupported command:" not in handle, handle
6189 # TODO: Check the version returned by this command
6190 if "Committed version" in handle:
6191 return main.TRUE
6192 else:
6193 return main.FALSE
6194 except AssertionError:
6195 main.log.exception( "" )
6196 return main.ERROR
6197 except TypeError:
6198 main.log.exception( self.name + ": Object not as expected" )
6199 return main.ERROR
6200 except pexpect.EOF:
6201 main.log.error( self.name + ": EOF exception found" )
6202 main.log.error( self.name + ": " + self.handle.before )
6203 main.cleanAndExit()
6204 except Exception:
6205 main.log.exception( self.name + ": Uncaught exception!" )
6206 main.cleanAndExit()
6207
6208 def issuRollback( self ):
6209 """
6210 Rolls back an In-Service Software Upgrade
6211
6212 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6213 """
6214 try:
6215 cmdStr = "issu rollback"
6216 handle = self.sendline( cmdStr )
6217 assert handle is not None, "Error in sendline"
6218 assert "Command not found:" not in handle, handle
6219 assert "Unsupported command:" not in handle, handle
6220 # TODO: Check the version returned by this command
6221 if "Rolled back to version" in handle:
6222 return main.TRUE
6223 else:
6224 return main.FALSE
6225 except AssertionError:
6226 main.log.exception( "" )
6227 return main.ERROR
6228 except TypeError:
6229 main.log.exception( self.name + ": Object not as expected" )
6230 return main.ERROR
6231 except pexpect.EOF:
6232 main.log.error( self.name + ": EOF exception found" )
6233 main.log.error( self.name + ": " + self.handle.before )
6234 main.cleanAndExit()
6235 except Exception:
6236 main.log.exception( self.name + ": Uncaught exception!" )
6237 main.cleanAndExit()
6238
6239 def issuReset( self ):
6240 """
6241 Resets the In-Service Software Upgrade status after a rollback
6242
6243 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6244 """
6245 try:
6246 cmdStr = "issu reset"
6247 handle = self.sendline( cmdStr )
6248 assert handle is not None, "Error in sendline"
6249 assert "Command not found:" not in handle, handle
6250 assert "Unsupported command:" not in handle, handle
6251 # TODO: Check the version returned by this command
6252 if "Reset version" in handle:
6253 return main.TRUE
6254 else:
6255 return main.FALSE
6256 except AssertionError:
6257 main.log.exception( "" )
6258 return main.ERROR
6259 except TypeError:
6260 main.log.exception( self.name + ": Object not as expected" )
6261 return main.ERROR
6262 except pexpect.EOF:
6263 main.log.error( self.name + ": EOF exception found" )
6264 main.log.error( self.name + ": " + self.handle.before )
6265 main.cleanAndExit()
6266 except Exception:
6267 main.log.exception( self.name + ": Uncaught exception!" )
6268 main.cleanAndExit()
6269
6270 def issuStatus( self ):
6271 """
6272 Status of an In-Service Software Upgrade
6273
6274 Returns the output of the cli command or None on Error
6275 """
6276 try:
6277 cmdStr = "issu status"
6278 handle = self.sendline( cmdStr )
6279 assert handle is not None, "Error in sendline"
6280 assert "Command not found:" not in handle, handle
6281 assert "Unsupported command:" not in handle, handle
6282 return handle
6283 except AssertionError:
6284 main.log.exception( "" )
6285 return None
6286 except TypeError:
6287 main.log.exception( self.name + ": Object not as expected" )
6288 return None
6289 except pexpect.EOF:
6290 main.log.error( self.name + ": EOF exception found" )
6291 main.log.error( self.name + ": " + self.handle.before )
6292 main.cleanAndExit()
6293 except Exception:
6294 main.log.exception( self.name + ": Uncaught exception!" )
6295 main.cleanAndExit()
6296
6297 def issuVersion( self ):
6298 """
6299 Get the version of an In-Service Software Upgrade
6300
6301 Returns the output of the cli command or None on Error
6302 """
6303 try:
6304 cmdStr = "issu version"
6305 handle = self.sendline( cmdStr )
6306 assert handle is not None, "Error in sendline"
6307 assert "Command not found:" not in handle, handle
6308 assert "Unsupported command:" not in handle, handle
6309 return handle
6310 except AssertionError:
6311 main.log.exception( "" )
6312 return None
6313 except TypeError:
6314 main.log.exception( self.name + ": Object not as expected" )
6315 return None
6316 except pexpect.EOF:
6317 main.log.error( self.name + ": EOF exception found" )
6318 main.log.error( self.name + ": " + self.handle.before )
6319 main.cleanAndExit()
6320 except Exception:
6321 main.log.exception( self.name + ": Uncaught exception!" )
6322 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006323
6324 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6325 """
6326 Create a multicast route by calling 'mcast-join' command
6327 sIP: source IP of the multicast route
6328 groupIP: group IP of the multicast route
6329 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6330 dPorts: a list of destination ports of the multicast route
6331 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6332 """
6333 try:
6334 cmdStr = "mcast-join"
6335 cmdStr += " " + str( sIP )
6336 cmdStr += " " + str( groupIP )
6337 cmdStr += " " + str( sPort )
6338 assert isinstance( dPorts, list )
6339 for dPort in dPorts:
6340 cmdStr += " " + str( dPort )
6341 handle = self.sendline( cmdStr )
6342 assert handle is not None, "Error in sendline"
6343 assert "Command not found:" not in handle, handle
6344 assert "Unsupported command:" not in handle, handle
6345 assert "Error executing command" not in handle, handle
6346 if "Added the mcast route" in handle:
6347 return main.TRUE
6348 else:
6349 return main.FALSE
6350 except AssertionError:
6351 main.log.exception( "" )
6352 return None
6353 except TypeError:
6354 main.log.exception( self.name + ": Object not as expected" )
6355 return None
6356 except pexpect.EOF:
6357 main.log.error( self.name + ": EOF exception found" )
6358 main.log.error( self.name + ": " + self.handle.before )
6359 main.cleanAndExit()
6360 except Exception:
6361 main.log.exception( self.name + ": Uncaught exception!" )
6362 main.cleanAndExit()
6363
6364 def mcastDelete( self, sIP, groupIP, dPorts ):
6365 """
6366 Delete a multicast route by calling 'mcast-delete' command
6367 sIP: source IP of the multicast route
6368 groupIP: group IP of the multicast route
6369 dPorts: a list of destination ports of the multicast route
6370 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6371 """
6372 try:
6373 cmdStr = "mcast-delete"
6374 cmdStr += " " + str( sIP )
6375 cmdStr += " " + str( groupIP )
6376 assert isinstance( dPorts, list )
6377 for dPort in dPorts:
6378 cmdStr += " " + str( dPort )
6379 handle = self.sendline( cmdStr )
6380 assert handle is not None, "Error in sendline"
6381 assert "Command not found:" not in handle, handle
6382 assert "Unsupported command:" not in handle, handle
6383 assert "Error executing command" not in handle, handle
6384 if "Updated the mcast route" in handle:
6385 return main.TRUE
6386 else:
6387 return main.FALSE
6388 except AssertionError:
6389 main.log.exception( "" )
6390 return None
6391 except TypeError:
6392 main.log.exception( self.name + ": Object not as expected" )
6393 return None
6394 except pexpect.EOF:
6395 main.log.error( self.name + ": EOF exception found" )
6396 main.log.error( self.name + ": " + self.handle.before )
6397 main.cleanAndExit()
6398 except Exception:
6399 main.log.exception( self.name + ": Uncaught exception!" )
6400 main.cleanAndExit()
6401
6402 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6403 """
6404 Create a multicast route by calling 'mcast-host-join' command
6405 sAddr: we can provide * for ASM or a specific address for SSM
6406 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006407 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006408 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6409 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6410 """
6411 try:
6412 cmdStr = "mcast-host-join"
6413 cmdStr += " -sAddr " + str( sAddr )
6414 cmdStr += " -gAddr " + str( gAddr )
6415 assert isinstance( srcs, list )
6416 for src in srcs:
6417 cmdStr += " -srcs " + str( src )
6418 assert isinstance( sinks, list )
6419 for sink in sinks:
6420 cmdStr += " -sinks " + str( sink )
6421 handle = self.sendline( cmdStr )
6422 assert handle is not None, "Error in sendline"
6423 assert "Command not found:" not in handle, handle
6424 assert "Unsupported command:" not in handle, handle
6425 assert "Error executing command" not in handle, handle
6426 if "Added the mcast route" in handle:
6427 return main.TRUE
6428 else:
6429 return main.FALSE
6430 except AssertionError:
6431 main.log.exception( "" )
6432 return None
6433 except TypeError:
6434 main.log.exception( self.name + ": Object not as expected" )
6435 return None
6436 except pexpect.EOF:
6437 main.log.error( self.name + ": EOF exception found" )
6438 main.log.error( self.name + ": " + self.handle.before )
6439 main.cleanAndExit()
6440 except Exception:
6441 main.log.exception( self.name + ": Uncaught exception!" )
6442 main.cleanAndExit()
6443
6444 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6445 """
6446 Delete multicast sink(s) by calling 'mcast-host-delete' command
6447 sAddr: we can provide * for ASM or a specific address for SSM
6448 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006449 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006450 will delete the route if not specified
6451 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6452 """
6453 try:
6454 cmdStr = "mcast-host-delete"
6455 cmdStr += " -sAddr " + str( sAddr )
6456 cmdStr += " -gAddr " + str( gAddr )
6457 if host:
6458 cmdStr += " -h " + str( host )
6459 handle = self.sendline( cmdStr )
6460 assert handle is not None, "Error in sendline"
6461 assert "Command not found:" not in handle, handle
6462 assert "Unsupported command:" not in handle, handle
6463 assert "Error executing command" not in handle, handle
6464 if "Updated the mcast route" in handle:
6465 return main.TRUE
6466 elif "Deleted the mcast route" in handle:
6467 return main.TRUE
6468 else:
6469 return main.FALSE
6470 except AssertionError:
6471 main.log.exception( "" )
6472 return None
6473 except TypeError:
6474 main.log.exception( self.name + ": Object not as expected" )
6475 return None
6476 except pexpect.EOF:
6477 main.log.error( self.name + ": EOF exception found" )
6478 main.log.error( self.name + ": " + self.handle.before )
6479 main.cleanAndExit()
6480 except Exception:
6481 main.log.exception( self.name + ": Uncaught exception!" )
6482 main.cleanAndExit()
6483
You Wang547893e2018-05-08 13:34:59 -07006484 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6485 """
6486 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6487 sAddr: we can provide * for ASM or a specific address for SSM
6488 gAddr: specifies multicast group address
6489 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6490 will delete the route if not specified
6491 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6492 """
6493 try:
6494 cmdStr = "mcast-sink-delete"
6495 cmdStr += " -sAddr " + str( sAddr )
6496 cmdStr += " -gAddr " + str( gAddr )
6497 if sink:
6498 cmdStr += " -s " + str( sink )
6499 handle = self.sendline( cmdStr )
6500 assert handle is not None, "Error in sendline"
6501 assert "Command not found:" not in handle, handle
6502 assert "Unsupported command:" not in handle, handle
6503 assert "Error executing command" not in handle, handle
6504 if "Updated the mcast route" in handle:
6505 return main.TRUE
6506 elif "Deleted the mcast route" in handle:
6507 return main.TRUE
6508 else:
6509 return main.FALSE
6510 except AssertionError:
6511 main.log.exception( "" )
6512 return None
6513 except TypeError:
6514 main.log.exception( self.name + ": Object not as expected" )
6515 return None
6516 except pexpect.EOF:
6517 main.log.error( self.name + ": EOF exception found" )
6518 main.log.error( self.name + ": " + self.handle.before )
6519 main.cleanAndExit()
6520 except Exception:
6521 main.log.exception( self.name + ": Uncaught exception!" )
6522 main.cleanAndExit()
6523
You Wange24d6272018-03-27 21:18:50 -07006524 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6525 """
6526 Delete multicast src(s) by calling 'mcast-source-delete' command
6527 sAddr: we can provide * for ASM or a specific address for SSM
6528 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006529 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 -07006530 will delete the route if not specified
6531 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6532 """
6533 try:
6534 cmdStr = "mcast-source-delete"
6535 cmdStr += " -sAddr " + str( sAddr )
6536 cmdStr += " -gAddr " + str( gAddr )
6537 if srcs:
6538 assert isinstance( srcs, list )
6539 for src in srcs:
6540 cmdStr += " -src " + str( src )
6541 handle = self.sendline( cmdStr )
6542 assert handle is not None, "Error in sendline"
6543 assert "Command not found:" not in handle, handle
6544 assert "Unsupported command:" not in handle, handle
6545 assert "Error executing command" not in handle, handle
6546 if "Updated the mcast route" in handle:
6547 return main.TRUE
6548 elif "Deleted the mcast route" in handle:
6549 return main.TRUE
6550 else:
6551 return main.FALSE
6552 except AssertionError:
6553 main.log.exception( "" )
6554 return None
6555 except TypeError:
6556 main.log.exception( self.name + ": Object not as expected" )
6557 return None
6558 except pexpect.EOF:
6559 main.log.error( self.name + ": EOF exception found" )
6560 main.log.error( self.name + ": " + self.handle.before )
6561 main.cleanAndExit()
6562 except Exception:
6563 main.log.exception( self.name + ": Uncaught exception!" )
6564 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006565
6566 def netcfg( self, jsonFormat=True, args="" ):
6567 """
6568 Run netcfg cli command with given args
6569 """
6570 try:
6571 cmdStr = "netcfg"
6572 if jsonFormat:
6573 cmdStr = cmdStr + " -j"
6574 if args:
6575 cmdStr = cmdStr + " " + str( args )
6576 handle = self.sendline( cmdStr )
6577 assert handle is not None, "Error in sendline"
6578 assert "Command not found:" not in handle, handle
6579 assert "Unsupported command:" not in handle, handle
6580 assert "Error executing command" not in handle, handle
6581 return handle
6582 except AssertionError:
6583 main.log.exception( "" )
6584 return None
6585 except TypeError:
6586 main.log.exception( self.name + ": Object not as expected" )
6587 return None
6588 except pexpect.EOF:
6589 main.log.error( self.name + ": EOF exception found" )
6590 main.log.error( self.name + ": " + self.handle.before )
6591 main.cleanAndExit()
6592 except Exception:
6593 main.log.exception( self.name + ": Uncaught exception!" )
6594 main.cleanAndExit()
6595
You Wang0fa76e72018-05-18 11:33:25 -07006596 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006597 """
You Wang54b1d672018-06-11 16:44:13 -07006598 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006599 Options:
6600 sAddr: IP address of the source host
6601 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006602 ipv6: True if hosts are IPv6
6603 verbose: return verbose t3 output if True
6604 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006605 """
6606 try:
6607 # Collect information of both hosts from onos
6608 hosts = self.hosts()
6609 hosts = json.loads( hosts )
6610 sHost = None
6611 dHost = None
6612 for host in hosts:
6613 if sAddr in host[ "ipAddresses" ]:
6614 sHost = host
6615 elif dAddr in host[ "ipAddresses" ]:
6616 dHost = host
6617 if sHost and dHost:
6618 break
6619 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006620 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006621 if simple:
6622 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006623 cmdStr = "t3-troubleshoot-simple"
6624 if verbose:
6625 cmdStr += " -vv"
6626 if ipv6:
6627 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006628 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006629 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006630 else:
You Wang54b1d672018-06-11 16:44:13 -07006631 for location in sHost[ "locations" ]:
6632 cmdStr = "t3-troubleshoot"
6633 if verbose:
6634 cmdStr += " -vv"
6635 if ipv6:
6636 cmdStr += " -et ipv6"
6637 cmdStr += " -s " + str( sAddr )
6638 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6639 cmdStr += " -sm " + str( sHost[ "mac" ] )
6640 if sHost[ "vlan" ] != "None":
6641 cmdStr += " -vid " + sHost[ "vlan" ]
6642 cmdStr += " -d " + str( dAddr )
6643 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6644 netcfg = json.loads( netcfg )
6645 assert netcfg, "Failed to get netcfg"
6646 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6647 cmdList.append( cmdStr )
6648 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006649 except AssertionError:
6650 main.log.exception( "" )
6651 return None
6652 except ( KeyError, TypeError ):
6653 main.log.exception( self.name + ": Object not as expected" )
6654 return None
6655 except Exception:
6656 main.log.exception( self.name + ": Uncaught exception!" )
6657 main.cleanAndExit()
6658
6659 def t3( self, sAddr, dAddr, ipv6=False ):
6660 """
You Wang54b1d672018-06-11 16:44:13 -07006661 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006662 Options:
6663 sAddr: IP address of the source host
6664 dAddr: IP address of the destination host
6665 """
6666 try:
You Wang54b1d672018-06-11 16:44:13 -07006667 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6668 assert cmdList is not None, "composeT3Command returned None"
6669 t3Output = ""
6670 for cmdStr in cmdList:
6671 handle = self.sendline( cmdStr )
6672 assert handle is not None, "Error in sendline"
6673 assert "Command not found:" not in handle, handle
6674 assert "Unsupported command:" not in handle, handle
6675 assert "Error executing command" not in handle, handle
6676 assert "Tracing packet" in handle
6677 t3Output += handle
6678 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006679 except AssertionError:
6680 main.log.exception( "" )
6681 return None
6682 except pexpect.EOF:
6683 main.log.error( self.name + ": EOF exception found" )
6684 main.log.error( self.name + ": " + self.handle.before )
6685 main.cleanAndExit()
6686 except Exception:
6687 main.log.exception( self.name + ": Uncaught exception!" )
6688 main.cleanAndExit()