blob: 7d790b638058e7aa78f97a91ad743111f3b1542a [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 Hall6c9e2da2018-11-06 12:01:23 -0800594 if relaxedRegex:
595 # This was added because karaf 4.2 is stripping some characters from the command echo
596 endStr = cmdStr.split( '|' )[-1]
Jon Hall6c9e2da2018-11-06 12:01:23 -0800597 output = response.split( endStr.strip(), 1 )
Jon Hall39e3ffe2018-12-05 11:40:29 -0800598 if len( output ) < 2:
599 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
600 output = response.split( endStr.strip()[-5:], 1 )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800601 else:
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800602 output = response.split( endStr.strip(), 1 )
603 if len( output ) < 2:
604 main.log.warn( "Relaxing regex match to last 5 characters of the sent command" )
Jon Hall0623dd42018-11-13 14:32:23 -0800605 output = response.split( endStr.strip()[-5:], 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700606 if output:
607 if debug:
608 main.log.debug( self.name + ": split output" )
609 for r in output:
610 main.log.debug( self.name + ": " + repr( r ) )
611 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800612 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800613 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700614 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800615 return output
GlennRCed771242016-01-13 17:02:47 -0800616 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700617 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800618 if debug:
619 main.log.debug( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700620 self.handle.send( "\x03" )
Jon Hall6c9e2da2018-11-06 12:01:23 -0800621 self.handle.expect( self.karafPrompt )
GlennRCed771242016-01-13 17:02:47 -0800622 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700623 except IndexError:
624 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700625 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700626 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800627 except TypeError:
628 main.log.exception( self.name + ": Object not as expected" )
629 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400630 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800631 main.log.error( self.name + ": EOF exception found" )
632 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700633 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700634 return None
635 else:
Devin Lim44075962017-08-11 10:56:37 -0700636 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800637 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800638 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700639 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700640 return None
641 else:
Devin Lim44075962017-08-11 10:56:37 -0700642 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400643
Jon Halld5a94fb2018-11-13 14:32:23 -0800644 def lineCount( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, relaxedRegex=True ):
645 """
646 A wrapper around sendline(). Will return the number of lines returned or None on error
647
648 Required Arguments:
649 cmdStr - String to send to the pexpect session
650
651 Optional Arguments:
652 showResponse - Defaults to False. If True will log the response.
653 debug - Defaults to False. If True, will enable debug logging.
654 timeout - Defaults to 10. Amount of time in seconds for a command to return
655 before a timeout.
656 noExit - Defaults to False. If True, will not exit TestON in the event of a
657 closed channel, but instead return None
658 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.
659
660 Warning: There are no sanity checking to commands sent using this method.
661
662 """
663 try:
664 numLines = self.sendline( cmdStr, showResponse, debug, timeout, noExit, relaxedRegex )
Jon Hall8c9dd1c2018-11-14 15:40:39 -0800665 parsed = re.search( "(\d+)\s+(\d+)", numLines )
666 if not parsed:
667 main.log.error( "Warning, output of karaf's wc may have changed" )
668 return None
669 return parsed.group( 1 )
Jon Halld5a94fb2018-11-13 14:32:23 -0800670 except IndexError:
671 main.log.exception( self.name + ": Object not as expected" )
672 main.log.debug( "response: {}".format( repr( response ) ) )
673 return None
674 except TypeError:
675 main.log.exception( self.name + ": Object not as expected" )
676 return None
677 except Exception:
678 main.log.exception( self.name + ": Uncaught exception!" )
679 if noExit:
680 return None
681 else:
682 main.cleanAndExit()
683
kelvin8ec71442015-01-15 16:57:00 -0800684 # IMPORTANT NOTE:
685 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800686 # the cli command changing 'a:b' with 'aB'.
687 # Ex ) onos:topology > onosTopology
688 # onos:links > onosLinks
689 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800690
kelvin-onlabd3b64892015-01-20 13:26:24 -0800691 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800692 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400693 Adds a new cluster node by ID and address information.
694 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800695 * nodeId
696 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400697 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800698 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800699 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400700 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800701 cmdStr = "add-node " + str( nodeId ) + " " +\
702 str( ONOSIp ) + " " + str( tcpPort )
703 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700704 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800705 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800706 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700707 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800708 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800709 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400710 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800711 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400712 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800713 except AssertionError:
714 main.log.exception( "" )
715 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800716 except TypeError:
717 main.log.exception( self.name + ": Object not as expected" )
718 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400719 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800720 main.log.error( self.name + ": EOF exception found" )
721 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700722 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800723 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800724 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700725 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400726
kelvin-onlabd3b64892015-01-20 13:26:24 -0800727 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800728 """
andrewonlab86dc3082014-10-13 18:18:38 -0400729 Removes a cluster by ID
730 Issues command: 'remove-node [<node-id>]'
731 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800732 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800733 """
andrewonlab86dc3082014-10-13 18:18:38 -0400734 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400735
kelvin-onlabd3b64892015-01-20 13:26:24 -0800736 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700737 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700738 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800739 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700740 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700741 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700742 main.log.error( handle )
743 return main.FALSE
744 else:
745 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800746 except AssertionError:
747 main.log.exception( "" )
748 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800749 except TypeError:
750 main.log.exception( self.name + ": Object not as expected" )
751 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400752 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800753 main.log.error( self.name + ": EOF exception found" )
754 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700755 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800756 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800757 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700758 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400759
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700760 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800761 """
andrewonlab7c211572014-10-15 16:45:20 -0400762 List the nodes currently visible
763 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700764 Optional argument:
765 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800766 """
andrewonlab7c211572014-10-15 16:45:20 -0400767 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700768 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700769 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700770 cmdStr += " -j"
771 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700772 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800773 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700774 return output
Jon Hallc6793552016-01-19 14:18:37 -0800775 except AssertionError:
776 main.log.exception( "" )
777 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800778 except TypeError:
779 main.log.exception( self.name + ": Object not as expected" )
780 return None
andrewonlab7c211572014-10-15 16:45:20 -0400781 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800782 main.log.error( self.name + ": EOF exception found" )
783 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700784 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800785 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800786 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700787 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400788
kelvin8ec71442015-01-15 16:57:00 -0800789 def topology( self ):
790 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700791 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700792 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700793 Return:
794 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800795 """
andrewonlab95ce8322014-10-13 14:12:04 -0400796 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700797 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800798 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800799 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800800 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700801 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400802 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800803 except AssertionError:
804 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800805 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800806 except TypeError:
807 main.log.exception( self.name + ": Object not as expected" )
808 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400809 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800810 main.log.error( self.name + ": EOF exception found" )
811 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700812 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800813 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800814 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700815 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800816
jenkins7ead5a82015-03-13 10:28:21 -0700817 def deviceRemove( self, deviceId ):
818 """
819 Removes particular device from storage
820
821 TODO: refactor this function
822 """
823 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700824 cmdStr = "device-remove " + str( deviceId )
825 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800826 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800827 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700828 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700829 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700830 main.log.error( handle )
831 return main.FALSE
832 else:
833 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800834 except AssertionError:
835 main.log.exception( "" )
836 return None
jenkins7ead5a82015-03-13 10:28:21 -0700837 except TypeError:
838 main.log.exception( self.name + ": Object not as expected" )
839 return None
840 except pexpect.EOF:
841 main.log.error( self.name + ": EOF exception found" )
842 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700843 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700844 except Exception:
845 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700846 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700847
You Wang3b9689a2018-08-30 12:24:00 -0700848 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800849 """
Jon Hall7b02d952014-10-17 20:14:54 -0400850 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400851 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800852 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800853 """
andrewonlab86dc3082014-10-13 18:18:38 -0400854 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700855 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800856 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700857 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700858 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800859 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800860 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700861 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800862 except AssertionError:
863 main.log.exception( "" )
864 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800865 except TypeError:
866 main.log.exception( self.name + ": Object not as expected" )
867 return None
andrewonlab7c211572014-10-15 16:45:20 -0400868 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800869 main.log.error( self.name + ": EOF exception found" )
870 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700871 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800872 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800873 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700874 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400875
kelvin-onlabd3b64892015-01-20 13:26:24 -0800876 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800877 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800878 This balances the devices across all controllers
879 by issuing command: 'onos> onos:balance-masters'
880 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800881 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800882 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800883 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700884 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800885 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800886 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700887 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700888 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700889 main.log.error( handle )
890 return main.FALSE
891 else:
892 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800893 except AssertionError:
894 main.log.exception( "" )
895 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800896 except TypeError:
897 main.log.exception( self.name + ": Object not as expected" )
898 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800899 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800900 main.log.error( self.name + ": EOF exception found" )
901 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700902 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800903 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800904 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700905 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800906
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000907 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700908 """
909 Returns the output of the masters command.
910 Optional argument:
911 * jsonFormat - boolean indicating if you want output in json
912 """
913 try:
914 cmdStr = "onos:masters"
915 if jsonFormat:
916 cmdStr += " -j"
917 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700918 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800919 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700920 return output
Jon Hallc6793552016-01-19 14:18:37 -0800921 except AssertionError:
922 main.log.exception( "" )
923 return None
acsmars24950022015-07-30 18:00:43 -0700924 except TypeError:
925 main.log.exception( self.name + ": Object not as expected" )
926 return None
927 except pexpect.EOF:
928 main.log.error( self.name + ": EOF exception found" )
929 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700930 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700931 except Exception:
932 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700933 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700934
Jon Hallc6793552016-01-19 14:18:37 -0800935 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700936 """
937 Uses the master command to check that the devices' leadership
938 is evenly divided
939
940 Dependencies: checkMasters() and summary()
941
Jon Hall6509dbf2016-06-21 17:01:17 -0700942 Returns main.TRUE if the devices are balanced
943 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700944 Exits on Exception
945 Returns None on TypeError
946 """
947 try:
Jon Hallc6793552016-01-19 14:18:37 -0800948 summaryOutput = self.summary()
949 totalDevices = json.loads( summaryOutput )[ "devices" ]
950 except ( TypeError, ValueError ):
951 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
952 return None
953 try:
acsmars24950022015-07-30 18:00:43 -0700954 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800955 mastersOutput = self.checkMasters()
956 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700957 first = masters[ 0 ][ "size" ]
958 for master in masters:
959 totalOwnedDevices += master[ "size" ]
960 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
961 main.log.error( "Mastership not balanced" )
962 main.log.info( "\n" + self.checkMasters( False ) )
963 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700964 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700965 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700966 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800967 except ( TypeError, ValueError ):
968 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700969 return None
970 except pexpect.EOF:
971 main.log.error( self.name + ": EOF exception found" )
972 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700973 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700974 except Exception:
975 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700976 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700977
YPZhangfebf7302016-05-24 16:45:56 -0700978 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800979 """
Jon Halle8217482014-10-17 13:49:14 -0400980 Lists all core links
981 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800982 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800983 """
Jon Halle8217482014-10-17 13:49:14 -0400984 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700985 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800986 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700987 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700988 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800989 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800990 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700991 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800992 except AssertionError:
993 main.log.exception( "" )
994 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800995 except TypeError:
996 main.log.exception( self.name + ": Object not as expected" )
997 return None
Jon Halle8217482014-10-17 13:49:14 -0400998 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800999 main.log.error( self.name + ": EOF exception found" )
1000 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001001 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001002 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001003 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001004 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001005
You Wang3b9689a2018-08-30 12:24:00 -07001006 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -08001007 """
Jon Halle8217482014-10-17 13:49:14 -04001008 Lists all ports
1009 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001010 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001011 """
Jon Halle8217482014-10-17 13:49:14 -04001012 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001013 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001015 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -07001016 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001017 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001018 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001019 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001020 except AssertionError:
1021 main.log.exception( "" )
1022 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001023 except TypeError:
1024 main.log.exception( self.name + ": Object not as expected" )
1025 return None
Jon Halle8217482014-10-17 13:49:14 -04001026 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001027 main.log.error( self.name + ": EOF exception found" )
1028 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001029 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001030 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001031 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001032 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -04001033
kelvin-onlabd3b64892015-01-20 13:26:24 -08001034 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001035 """
Jon Hall983a1702014-10-28 18:44:22 -04001036 Lists all devices and the controllers with roles assigned to them
1037 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001038 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001039 """
andrewonlab7c211572014-10-15 16:45:20 -04001040 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001041 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001042 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001043 cmdStr += " -j"
1044 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001045 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001046 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001047 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001048 except AssertionError:
1049 main.log.exception( "" )
1050 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001051 except TypeError:
1052 main.log.exception( self.name + ": Object not as expected" )
1053 return None
Jon Hall983a1702014-10-28 18:44:22 -04001054 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001055 main.log.error( self.name + ": EOF exception found" )
1056 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001057 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001058 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001059 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001060 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -04001061
kelvin-onlabd3b64892015-01-20 13:26:24 -08001062 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001063 """
Jon Halle3f39ff2015-01-13 11:50:53 -08001064 Given the a string containing the json representation of the "roles"
1065 cli command and a partial or whole device id, returns a json object
1066 containing the roles output for the first device whose id contains
1067 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001068
1069 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001070 A dict of the role assignments for the given device or
1071 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001072 """
Jon Hall983a1702014-10-28 18:44:22 -04001073 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001074 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001075 return None
1076 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001077 rawRoles = self.roles()
1078 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001079 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001080 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001081 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001082 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001083 return device
1084 return None
Jon Hallc6793552016-01-19 14:18:37 -08001085 except ( TypeError, ValueError ):
1086 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001087 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001088 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001089 main.log.error( self.name + ": EOF exception found" )
1090 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001091 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001092 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001093 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001094 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001095
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001097 """
Jon Hall94fd0472014-12-08 11:52:42 -08001098 Iterates through each device and checks if there is a master assigned
1099 Returns: main.TRUE if each device has a master
1100 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001101 """
Jon Hall94fd0472014-12-08 11:52:42 -08001102 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001103 rawRoles = self.roles()
1104 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001105 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001106 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001107 # print device
1108 if device[ 'master' ] == "none":
1109 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001110 return main.FALSE
1111 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001112 except ( TypeError, ValueError ):
1113 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001114 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001115 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001116 main.log.error( self.name + ": EOF exception found" )
1117 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001118 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001119 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001120 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001121 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001122
kelvin-onlabd3b64892015-01-20 13:26:24 -08001123 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001124 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001125 Returns string of paths, and the cost.
1126 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001127 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001128 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1130 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001131 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001132 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001133 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001134 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001135 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001136 else:
kelvin8ec71442015-01-15 16:57:00 -08001137 path = handle.split( ";" )[ 0 ]
1138 cost = handle.split( ";" )[ 1 ]
1139 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001140 except AssertionError:
1141 main.log.exception( "" )
1142 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001143 except TypeError:
1144 main.log.exception( self.name + ": Object not as expected" )
1145 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001146 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001147 main.log.error( self.name + ": EOF exception found" )
1148 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001149 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001150 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001151 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001152 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001153
kelvin-onlabd3b64892015-01-20 13:26:24 -08001154 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001155 """
Jon Hallffb386d2014-11-21 13:43:38 -08001156 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001157 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001158 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001159 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001160 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001161 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001162 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001163 cmdStr += " -j"
1164 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001165 if handle:
1166 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001167 # TODO: Maybe make this less hardcoded
1168 # ConsistentMap Exceptions
1169 assert "org.onosproject.store.service" not in handle
1170 # Node not leader
1171 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001172 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001173 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001174 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001175 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001176 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001177 except TypeError:
1178 main.log.exception( self.name + ": Object not as expected" )
1179 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001180 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001181 main.log.error( self.name + ": EOF exception found" )
1182 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001183 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001184 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001185 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001186 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001187
kelvin-onlabd3b64892015-01-20 13:26:24 -08001188 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001189 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001190 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001191
Jon Hallefbd9792015-03-05 16:11:36 -08001192 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001193 partial mac address
1194
Jon Hall42db6dc2014-10-24 19:03:48 -04001195 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001196 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001197 try:
kelvin8ec71442015-01-15 16:57:00 -08001198 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001199 return None
1200 else:
1201 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001202 rawHosts = self.hosts()
1203 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001204 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001205 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001206 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001207 if not host:
1208 pass
1209 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001210 return host
1211 return None
Jon Hallc6793552016-01-19 14:18:37 -08001212 except ( TypeError, ValueError ):
1213 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001214 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001215 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001216 main.log.error( self.name + ": EOF exception found" )
1217 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001218 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001219 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001220 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001221 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001222
kelvin-onlabd3b64892015-01-20 13:26:24 -08001223 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001224 """
1225 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001226 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001227
andrewonlab3f0a4af2014-10-17 12:25:14 -04001228 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001229 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001230 IMPORTANT:
1231 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001232 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001233 Furthermore, it assumes that value of VLAN is '-1'
1234 Description:
kelvin8ec71442015-01-15 16:57:00 -08001235 Converts mininet hosts ( h1, h2, h3... ) into
1236 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1237 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001238 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001239 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001240
kelvin-onlabd3b64892015-01-20 13:26:24 -08001241 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001242 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001243 hostHex = hex( int( host ) ).zfill( 12 )
1244 hostHex = str( hostHex ).replace( 'x', '0' )
1245 i = iter( str( hostHex ) )
1246 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1247 hostHex = hostHex + "/-1"
1248 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001249
kelvin-onlabd3b64892015-01-20 13:26:24 -08001250 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001251
Jon Halld4d4b372015-01-28 16:02:41 -08001252 except TypeError:
1253 main.log.exception( self.name + ": Object not as expected" )
1254 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001255 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001256 main.log.error( self.name + ": EOF exception found" )
1257 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001258 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001259 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001260 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001261 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001262
You Wangbc898b82018-05-03 16:22:34 -07001263 def verifyHostLocation( self, hostIp, location ):
1264 """
1265 Description:
1266 Verify the host given is discovered in all locations expected
1267 Required:
1268 hostIp: IP address of the host
1269 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1270 Could be a string or list
1271 Returns:
1272 main.TRUE if host is discovered on all locations provided
1273 main.FALSE otherwise
1274 """
1275 import json
1276 locations = [ location ] if isinstance( location, str ) else location
1277 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1278 try:
1279 hosts = self.hosts()
1280 hosts = json.loads( hosts )
1281 targetHost = None
1282 for host in hosts:
1283 if hostIp in host[ "ipAddresses" ]:
1284 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001285 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001286 result = main.TRUE
1287 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1288 for loc in locations:
1289 discovered = False
1290 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001291 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1292 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001293 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001294 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001295 break
1296 if discovered:
1297 locationsDiscovered.remove( locDiscovered )
1298 else:
1299 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1300 result = main.FALSE
1301 if locationsDiscovered:
1302 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1303 result = main.FALSE
1304 return result
1305 except KeyError:
1306 main.log.exception( self.name + ": host data not as expected: " + hosts )
1307 return None
1308 except pexpect.EOF:
1309 main.log.error( self.name + ": EOF exception found" )
1310 main.log.error( self.name + ": " + self.handle.before )
1311 main.cleanAndExit()
1312 except Exception:
1313 main.log.exception( self.name + ": Uncaught exception" )
1314 return None
1315
You Wang53dba1e2018-02-02 17:45:44 -08001316 def verifyHostIp( self, hostList=[], prefix="" ):
1317 """
1318 Description:
1319 Verify that all hosts have IP address assigned to them
1320 Optional:
1321 hostList: If specified, verifications only happen to the hosts
1322 in hostList
1323 prefix: at least one of the ip address assigned to the host
1324 needs to have the specified prefix
1325 Returns:
1326 main.TRUE if all hosts have specific IP address assigned;
1327 main.FALSE otherwise
1328 """
1329 import json
1330 try:
1331 hosts = self.hosts()
1332 hosts = json.loads( hosts )
1333 if not hostList:
1334 hostList = [ host[ "id" ] for host in hosts ]
1335 for host in hosts:
1336 hostId = host[ "id" ]
1337 if hostId not in hostList:
1338 continue
1339 ipList = host[ "ipAddresses" ]
1340 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1341 if not ipList:
1342 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1343 else:
1344 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1345 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1346 else:
1347 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1348 hostList.remove( hostId )
1349 if hostList:
1350 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1351 return main.FALSE
1352 else:
1353 return main.TRUE
1354 except KeyError:
1355 main.log.exception( self.name + ": host data not as expected: " + hosts )
1356 return None
1357 except pexpect.EOF:
1358 main.log.error( self.name + ": EOF exception found" )
1359 main.log.error( self.name + ": " + self.handle.before )
1360 main.cleanAndExit()
1361 except Exception:
1362 main.log.exception( self.name + ": Uncaught exception" )
1363 return None
1364
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001365 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001366 """
andrewonlabe6745342014-10-17 14:29:13 -04001367 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001368 * hostIdOne: ONOS host id for host1
1369 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001370 Optional:
1371 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001372 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001373 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001374 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001375 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001376 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001377 Returns:
1378 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001379 """
andrewonlabe6745342014-10-17 14:29:13 -04001380 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001381 cmdStr = "add-host-intent "
1382 if vlanId:
1383 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001384 if setVlan:
1385 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001386 if encap:
1387 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001388 if bandwidth:
1389 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001390 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001391 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001392 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001393 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001394 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001395 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001396 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001397 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001398 else:
1399 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001400 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001401 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001402 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001403 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001404 else:
1405 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001406 main.log.debug( "Response from ONOS was: " +
1407 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001408 return None
Jon Hallc6793552016-01-19 14:18:37 -08001409 except AssertionError:
1410 main.log.exception( "" )
1411 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001412 except TypeError:
1413 main.log.exception( self.name + ": Object not as expected" )
1414 return None
andrewonlabe6745342014-10-17 14:29:13 -04001415 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001416 main.log.error( self.name + ": EOF exception found" )
1417 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001418 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001419 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001420 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001421 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001422
kelvin-onlabd3b64892015-01-20 13:26:24 -08001423 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001424 """
andrewonlab7b31d232014-10-24 13:31:47 -04001425 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001426 * ingressDevice: device id of ingress device
1427 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001428 Optional:
1429 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001430 Description:
1431 Adds an optical intent by specifying an ingress and egress device
1432 Returns:
1433 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001434 """
andrewonlab7b31d232014-10-24 13:31:47 -04001435 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001436 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1437 " " + str( egressDevice )
1438 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001439 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001440 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001441 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001442 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001443 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001444 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001445 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001446 main.log.info( "Optical intent installed between " +
1447 str( ingressDevice ) + " and " +
1448 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001449 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001450 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001451 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001452 else:
1453 main.log.error( "Error, intent ID not found" )
1454 return None
Jon Hallc6793552016-01-19 14:18:37 -08001455 except AssertionError:
1456 main.log.exception( "" )
1457 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001458 except TypeError:
1459 main.log.exception( self.name + ": Object not as expected" )
1460 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001461 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001462 main.log.error( self.name + ": EOF exception found" )
1463 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001464 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001465 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001466 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001467 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001468
kelvin-onlabd3b64892015-01-20 13:26:24 -08001469 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001470 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001471 ingressDevice,
1472 egressDevice,
1473 portIngress="",
1474 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001475 ethType="",
1476 ethSrc="",
1477 ethDst="",
1478 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001479 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001480 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001481 ipProto="",
1482 ipSrc="",
1483 ipDst="",
1484 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001485 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001486 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001487 setVlan="",
1488 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001489 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001490 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001491 * ingressDevice: device id of ingress device
1492 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001493 Optional:
1494 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001495 * ethSrc: specify ethSrc ( i.e. src mac addr )
1496 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001497 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001498 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001499 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001500 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001501 * ipSrc: specify ip source address
1502 * ipDst: specify ip destination address
1503 * tcpSrc: specify tcp source port
1504 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001505 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001506 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001507 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001508 Description:
kelvin8ec71442015-01-15 16:57:00 -08001509 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001510 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001511 Returns:
1512 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001513
Jon Halle3f39ff2015-01-13 11:50:53 -08001514 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001515 options developers provide for point-to-point
1516 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001517 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001518 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001519 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001520
Jeremy Songsterff553672016-05-12 17:06:23 -07001521 if ethType:
1522 cmd += " --ethType " + str( ethType )
1523 if ethSrc:
1524 cmd += " --ethSrc " + str( ethSrc )
1525 if ethDst:
1526 cmd += " --ethDst " + str( ethDst )
1527 if bandwidth:
1528 cmd += " --bandwidth " + str( bandwidth )
1529 if lambdaAlloc:
1530 cmd += " --lambda "
1531 if ipProto:
1532 cmd += " --ipProto " + str( ipProto )
1533 if ipSrc:
1534 cmd += " --ipSrc " + str( ipSrc )
1535 if ipDst:
1536 cmd += " --ipDst " + str( ipDst )
1537 if tcpSrc:
1538 cmd += " --tcpSrc " + str( tcpSrc )
1539 if tcpDst:
1540 cmd += " --tcpDst " + str( tcpDst )
1541 if vlanId:
1542 cmd += " -v " + str( vlanId )
1543 if setVlan:
1544 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001545 if encap:
1546 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001547 if protected:
1548 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001549
kelvin8ec71442015-01-15 16:57:00 -08001550 # Check whether the user appended the port
1551 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001552 if "/" in ingressDevice:
1553 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001554 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001555 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001556 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001557 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001558 # Would it make sense to throw an exception and exit
1559 # the test?
1560 return None
andrewonlab36af3822014-11-18 17:48:18 -05001561
kelvin8ec71442015-01-15 16:57:00 -08001562 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001563 str( ingressDevice ) + "/" +\
1564 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001565
kelvin-onlabd3b64892015-01-20 13:26:24 -08001566 if "/" in egressDevice:
1567 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001568 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001569 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001570 main.log.error( "You must specify the egress port" )
1571 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001572
kelvin8ec71442015-01-15 16:57:00 -08001573 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 str( egressDevice ) + "/" +\
1575 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001576
kelvin-onlab898a6c62015-01-16 14:13:53 -08001577 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001578 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001579 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001580 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001581 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001582 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001583 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001584 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001585 # TODO: print out all the options in this message?
1586 main.log.info( "Point-to-point intent installed between " +
1587 str( ingressDevice ) + " and " +
1588 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001589 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001590 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001591 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001592 else:
1593 main.log.error( "Error, intent ID not found" )
1594 return None
Jon Hallc6793552016-01-19 14:18:37 -08001595 except AssertionError:
1596 main.log.exception( "" )
1597 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001598 except TypeError:
1599 main.log.exception( self.name + ": Object not as expected" )
1600 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001601 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001602 main.log.error( self.name + ": EOF exception found" )
1603 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001604 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001605 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001606 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001607 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001608
kelvin-onlabd3b64892015-01-20 13:26:24 -08001609 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001610 self,
shahshreyac2f97072015-03-19 17:04:29 -07001611 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001612 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001613 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001614 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001615 ethType="",
1616 ethSrc="",
1617 ethDst="",
1618 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001619 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001620 ipProto="",
1621 ipSrc="",
1622 ipDst="",
1623 tcpSrc="",
1624 tcpDst="",
1625 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001626 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001627 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001628 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001629 partial=False,
1630 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001631 """
shahshreyad0c80432014-12-04 16:56:05 -08001632 Note:
shahshreya70622b12015-03-19 17:19:00 -07001633 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001634 is same. That is, all ingress devices include port numbers
1635 with a "/" or all ingress devices could specify device
1636 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001637 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001638 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001639 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001640 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001641 Optional:
1642 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001643 * ethSrc: specify ethSrc ( i.e. src mac addr )
1644 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001645 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001646 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001647 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001648 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001649 * ipSrc: specify ip source address
1650 * ipDst: specify ip destination address
1651 * tcpSrc: specify tcp source port
1652 * tcpDst: specify tcp destination port
1653 * setEthSrc: action to Rewrite Source MAC Address
1654 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001655 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001656 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001657 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001658 Description:
kelvin8ec71442015-01-15 16:57:00 -08001659 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001660 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001661 Returns:
1662 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001663
Jon Halle3f39ff2015-01-13 11:50:53 -08001664 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001665 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001666 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001667 """
shahshreyad0c80432014-12-04 16:56:05 -08001668 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001669 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001670
Jeremy Songsterff553672016-05-12 17:06:23 -07001671 if ethType:
1672 cmd += " --ethType " + str( ethType )
1673 if ethSrc:
1674 cmd += " --ethSrc " + str( ethSrc )
1675 if ethDst:
1676 cmd += " --ethDst " + str( ethDst )
1677 if bandwidth:
1678 cmd += " --bandwidth " + str( bandwidth )
1679 if lambdaAlloc:
1680 cmd += " --lambda "
1681 if ipProto:
1682 cmd += " --ipProto " + str( ipProto )
1683 if ipSrc:
1684 cmd += " --ipSrc " + str( ipSrc )
1685 if ipDst:
1686 cmd += " --ipDst " + str( ipDst )
1687 if tcpSrc:
1688 cmd += " --tcpSrc " + str( tcpSrc )
1689 if tcpDst:
1690 cmd += " --tcpDst " + str( tcpDst )
1691 if setEthSrc:
1692 cmd += " --setEthSrc " + str( setEthSrc )
1693 if setEthDst:
1694 cmd += " --setEthDst " + str( setEthDst )
1695 if vlanId:
1696 cmd += " -v " + str( vlanId )
1697 if setVlan:
1698 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001699 if partial:
1700 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001701 if encap:
1702 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001703
kelvin8ec71442015-01-15 16:57:00 -08001704 # Check whether the user appended the port
1705 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001706
1707 if portIngressList is None:
1708 for ingressDevice in ingressDeviceList:
1709 if "/" in ingressDevice:
1710 cmd += " " + str( ingressDevice )
1711 else:
1712 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001713 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001714 # TODO: perhaps more meaningful return
1715 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001716 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001717 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001718 for ingressDevice, portIngress in zip( ingressDeviceList,
1719 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001720 cmd += " " + \
1721 str( ingressDevice ) + "/" +\
1722 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001723 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001724 main.log.error( "Device list and port list does not " +
1725 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001726 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001727 if "/" in egressDevice:
1728 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001729 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001730 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001731 main.log.error( "You must specify " +
1732 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001733 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001734
kelvin8ec71442015-01-15 16:57:00 -08001735 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001736 str( egressDevice ) + "/" +\
1737 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001738 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001739 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001740 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001741 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001742 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001743 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001744 "intent" )
1745 return None
shahshreyad0c80432014-12-04 16:56:05 -08001746 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001747 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001748 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001749 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001750 else:
1751 main.log.error( "Error, intent ID not found" )
1752 return None
Jon Hallc6793552016-01-19 14:18:37 -08001753 except AssertionError:
1754 main.log.exception( "" )
1755 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001756 except TypeError:
1757 main.log.exception( self.name + ": Object not as expected" )
1758 return None
1759 except pexpect.EOF:
1760 main.log.error( self.name + ": EOF exception found" )
1761 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001762 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001763 except Exception:
1764 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001765 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001766
1767 def addSinglepointToMultipointIntent(
1768 self,
1769 ingressDevice,
1770 egressDeviceList,
1771 portIngress="",
1772 portEgressList=None,
1773 ethType="",
1774 ethSrc="",
1775 ethDst="",
1776 bandwidth="",
1777 lambdaAlloc=False,
1778 ipProto="",
1779 ipSrc="",
1780 ipDst="",
1781 tcpSrc="",
1782 tcpDst="",
1783 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001784 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001785 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001786 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001787 partial=False,
1788 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001789 """
1790 Note:
1791 This function assumes the format of all egress devices
1792 is same. That is, all egress devices include port numbers
1793 with a "/" or all egress devices could specify device
1794 ids and port numbers seperately.
1795 Required:
1796 * EgressDeviceList: List of device ids of egress device
1797 ( Atleast 2 eress devices required in the list )
1798 * ingressDevice: device id of ingress device
1799 Optional:
1800 * ethType: specify ethType
1801 * ethSrc: specify ethSrc ( i.e. src mac addr )
1802 * ethDst: specify ethDst ( i.e. dst mac addr )
1803 * bandwidth: specify bandwidth capacity of link
1804 * lambdaAlloc: if True, intent will allocate lambda
1805 for the specified intent
1806 * ipProto: specify ip protocol
1807 * ipSrc: specify ip source address
1808 * ipDst: specify ip destination address
1809 * tcpSrc: specify tcp source port
1810 * tcpDst: specify tcp destination port
1811 * setEthSrc: action to Rewrite Source MAC Address
1812 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001813 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001814 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001815 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001816 Description:
1817 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1818 specifying device id's and optional fields
1819 Returns:
1820 A string of the intent id or None on error
1821
1822 NOTE: This function may change depending on the
1823 options developers provide for singlepoint-to-multipoint
1824 intent via cli
1825 """
1826 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001827 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001828
Jeremy Songsterff553672016-05-12 17:06:23 -07001829 if ethType:
1830 cmd += " --ethType " + str( ethType )
1831 if ethSrc:
1832 cmd += " --ethSrc " + str( ethSrc )
1833 if ethDst:
1834 cmd += " --ethDst " + str( ethDst )
1835 if bandwidth:
1836 cmd += " --bandwidth " + str( bandwidth )
1837 if lambdaAlloc:
1838 cmd += " --lambda "
1839 if ipProto:
1840 cmd += " --ipProto " + str( ipProto )
1841 if ipSrc:
1842 cmd += " --ipSrc " + str( ipSrc )
1843 if ipDst:
1844 cmd += " --ipDst " + str( ipDst )
1845 if tcpSrc:
1846 cmd += " --tcpSrc " + str( tcpSrc )
1847 if tcpDst:
1848 cmd += " --tcpDst " + str( tcpDst )
1849 if setEthSrc:
1850 cmd += " --setEthSrc " + str( setEthSrc )
1851 if setEthDst:
1852 cmd += " --setEthDst " + str( setEthDst )
1853 if vlanId:
1854 cmd += " -v " + str( vlanId )
1855 if setVlan:
1856 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001857 if partial:
1858 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001859 if encap:
1860 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001861
1862 # Check whether the user appended the port
1863 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001864
kelvin-onlabb9408212015-04-01 13:34:04 -07001865 if "/" in ingressDevice:
1866 cmd += " " + str( ingressDevice )
1867 else:
1868 if not portIngress:
1869 main.log.error( "You must specify " +
1870 "the Ingress port" )
1871 return main.FALSE
1872
1873 cmd += " " +\
1874 str( ingressDevice ) + "/" +\
1875 str( portIngress )
1876
1877 if portEgressList is None:
1878 for egressDevice in egressDeviceList:
1879 if "/" in egressDevice:
1880 cmd += " " + str( egressDevice )
1881 else:
1882 main.log.error( "You must specify " +
1883 "the egress port" )
1884 # TODO: perhaps more meaningful return
1885 return main.FALSE
1886 else:
1887 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001888 for egressDevice, portEgress in zip( egressDeviceList,
1889 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001890 cmd += " " + \
1891 str( egressDevice ) + "/" +\
1892 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001893 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001894 main.log.error( "Device list and port list does not " +
1895 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001896 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001897 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001898 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001899 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001900 # If error, return error message
1901 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001902 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001903 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001904 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001905 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001906 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001907 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001908 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001909 else:
1910 main.log.error( "Error, intent ID not found" )
1911 return None
Jon Hallc6793552016-01-19 14:18:37 -08001912 except AssertionError:
1913 main.log.exception( "" )
1914 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001915 except TypeError:
1916 main.log.exception( self.name + ": Object not as expected" )
1917 return None
shahshreyad0c80432014-12-04 16:56:05 -08001918 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001919 main.log.error( self.name + ": EOF exception found" )
1920 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001921 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001922 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001923 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001924 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001925
Hari Krishna9e232602015-04-13 17:29:08 -07001926 def addMplsIntent(
1927 self,
1928 ingressDevice,
1929 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001930 ingressPort="",
1931 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001932 ethType="",
1933 ethSrc="",
1934 ethDst="",
1935 bandwidth="",
1936 lambdaAlloc=False,
1937 ipProto="",
1938 ipSrc="",
1939 ipDst="",
1940 tcpSrc="",
1941 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001942 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001943 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001944 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001945 """
1946 Required:
1947 * ingressDevice: device id of ingress device
1948 * egressDevice: device id of egress device
1949 Optional:
1950 * ethType: specify ethType
1951 * ethSrc: specify ethSrc ( i.e. src mac addr )
1952 * ethDst: specify ethDst ( i.e. dst mac addr )
1953 * bandwidth: specify bandwidth capacity of link
1954 * lambdaAlloc: if True, intent will allocate lambda
1955 for the specified intent
1956 * ipProto: specify ip protocol
1957 * ipSrc: specify ip source address
1958 * ipDst: specify ip destination address
1959 * tcpSrc: specify tcp source port
1960 * tcpDst: specify tcp destination port
1961 * ingressLabel: Ingress MPLS label
1962 * egressLabel: Egress MPLS label
1963 Description:
1964 Adds MPLS intent by
1965 specifying device id's and optional fields
1966 Returns:
1967 A string of the intent id or None on error
1968
1969 NOTE: This function may change depending on the
1970 options developers provide for MPLS
1971 intent via cli
1972 """
1973 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001974 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001975
Jeremy Songsterff553672016-05-12 17:06:23 -07001976 if ethType:
1977 cmd += " --ethType " + str( ethType )
1978 if ethSrc:
1979 cmd += " --ethSrc " + str( ethSrc )
1980 if ethDst:
1981 cmd += " --ethDst " + str( ethDst )
1982 if bandwidth:
1983 cmd += " --bandwidth " + str( bandwidth )
1984 if lambdaAlloc:
1985 cmd += " --lambda "
1986 if ipProto:
1987 cmd += " --ipProto " + str( ipProto )
1988 if ipSrc:
1989 cmd += " --ipSrc " + str( ipSrc )
1990 if ipDst:
1991 cmd += " --ipDst " + str( ipDst )
1992 if tcpSrc:
1993 cmd += " --tcpSrc " + str( tcpSrc )
1994 if tcpDst:
1995 cmd += " --tcpDst " + str( tcpDst )
1996 if ingressLabel:
1997 cmd += " --ingressLabel " + str( ingressLabel )
1998 if egressLabel:
1999 cmd += " --egressLabel " + str( egressLabel )
2000 if priority:
2001 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07002002
2003 # Check whether the user appended the port
2004 # or provided it as an input
2005 if "/" in ingressDevice:
2006 cmd += " " + str( ingressDevice )
2007 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002008 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002009 main.log.error( "You must specify the ingress port" )
2010 return None
2011
2012 cmd += " " + \
2013 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002014 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07002015
2016 if "/" in egressDevice:
2017 cmd += " " + str( egressDevice )
2018 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07002019 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07002020 main.log.error( "You must specify the egress port" )
2021 return None
2022
2023 cmd += " " +\
2024 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07002025 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07002026
2027 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08002028 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002029 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07002030 # If error, return error message
2031 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002032 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07002033 return None
2034 else:
2035 # TODO: print out all the options in this message?
2036 main.log.info( "MPLS intent installed between " +
2037 str( ingressDevice ) + " and " +
2038 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002039 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07002040 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002041 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07002042 else:
2043 main.log.error( "Error, intent ID not found" )
2044 return None
Jon Hallc6793552016-01-19 14:18:37 -08002045 except AssertionError:
2046 main.log.exception( "" )
2047 return None
Hari Krishna9e232602015-04-13 17:29:08 -07002048 except TypeError:
2049 main.log.exception( self.name + ": Object not as expected" )
2050 return None
2051 except pexpect.EOF:
2052 main.log.error( self.name + ": EOF exception found" )
2053 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002054 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002055 except Exception:
2056 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002057 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07002058
Jon Hallefbd9792015-03-05 16:11:36 -08002059 def removeIntent( self, intentId, app='org.onosproject.cli',
2060 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08002061 """
shahshreya1c818fc2015-02-26 13:44:08 -08002062 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07002063 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08002064 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07002065 -p or --purge: Purge the intent from the store after removal
2066
Jon Halle3f39ff2015-01-13 11:50:53 -08002067 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002068 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002069 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002070 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002071 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002072 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002073 if purge:
2074 cmdStr += " -p"
2075 if sync:
2076 cmdStr += " -s"
2077
2078 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002079 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002080 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002081 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002082 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002083 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002084 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002085 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002086 # TODO: Should this be main.TRUE
2087 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002088 except AssertionError:
2089 main.log.exception( "" )
2090 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002091 except TypeError:
2092 main.log.exception( self.name + ": Object not as expected" )
2093 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002094 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002095 main.log.error( self.name + ": EOF exception found" )
2096 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002097 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002098 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002099 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002100 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002101
YPZhangfebf7302016-05-24 16:45:56 -07002102 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002103 """
2104 Description:
2105 Remove all the intents
2106 Optional args:-
2107 -s or --sync: Waits for the removal before returning
2108 -p or --purge: Purge the intent from the store after removal
2109 Returns:
2110 Returns main.TRUE if all intents are removed, otherwise returns
2111 main.FALSE; Returns None for exception
2112 """
2113 try:
2114 cmdStr = "remove-intent"
2115 if purge:
2116 cmdStr += " -p"
2117 if sync:
2118 cmdStr += " -s"
2119
2120 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002121 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002122 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002123 assert "Command not found:" not in handle, handle
2124 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002125 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002126 return main.FALSE
2127 else:
2128 return main.TRUE
2129 except AssertionError:
2130 main.log.exception( "" )
2131 return None
2132 except TypeError:
2133 main.log.exception( self.name + ": Object not as expected" )
2134 return None
2135 except pexpect.EOF:
2136 main.log.error( self.name + ": EOF exception found" )
2137 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002138 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002139 except Exception:
2140 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002141 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002142
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002143 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002144 """
2145 Purges all WITHDRAWN Intents
2146 """
2147 try:
2148 cmdStr = "purge-intents"
2149 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002150 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002151 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002152 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002153 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002154 return main.FALSE
2155 else:
2156 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002157 except AssertionError:
2158 main.log.exception( "" )
2159 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002160 except TypeError:
2161 main.log.exception( self.name + ": Object not as expected" )
2162 return None
2163 except pexpect.EOF:
2164 main.log.error( self.name + ": EOF exception found" )
2165 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002166 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002167 except Exception:
2168 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002169 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002170
Devin Lime6fe3c42017-10-18 16:28:40 -07002171 def wipeout( self ):
2172 """
2173 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2174 """
2175 try:
2176 cmdStr = "wipe-out please"
2177 handle = self.sendline( cmdStr, timeout=60 )
2178 assert handle is not None, "Error in sendline"
2179 assert "Command not found:" not in handle, handle
2180 return main.TRUE
2181 except AssertionError:
2182 main.log.exception( "" )
2183 return None
2184 except TypeError:
2185 main.log.exception( self.name + ": Object not as expected" )
2186 return None
2187 except pexpect.EOF:
2188 main.log.error( self.name + ": EOF exception found" )
2189 main.log.error( self.name + ": " + self.handle.before )
2190 main.cleanAndExit()
2191 except Exception:
2192 main.log.exception( self.name + ": Uncaught exception!" )
2193 main.cleanAndExit()
2194
kelvin-onlabd3b64892015-01-20 13:26:24 -08002195 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002196 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002197 NOTE: This method should be used after installing application:
2198 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002199 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002200 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002201 Description:
2202 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002203 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002204 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002205 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002206 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002207 cmdStr += " -j"
2208 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002209 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002210 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002211 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002212 except AssertionError:
2213 main.log.exception( "" )
2214 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002215 except TypeError:
2216 main.log.exception( self.name + ": Object not as expected" )
2217 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002218 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002219 main.log.error( self.name + ": EOF exception found" )
2220 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002221 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002222 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002223 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002224 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002225
pingping-lin54b03372015-08-13 14:43:10 -07002226 def ipv4RouteNumber( self ):
2227 """
2228 NOTE: This method should be used after installing application:
2229 onos-app-sdnip
2230 Description:
2231 Obtain the total IPv4 routes number in the system
2232 """
2233 try:
Pratik Parab57963572017-05-09 11:37:54 -07002234 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002235 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002236 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002237 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002238 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002239 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002240 except AssertionError:
2241 main.log.exception( "" )
2242 return None
2243 except ( TypeError, ValueError ):
2244 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002245 return None
2246 except pexpect.EOF:
2247 main.log.error( self.name + ": EOF exception found" )
2248 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002249 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002250 except Exception:
2251 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002252 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002253
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002254 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002255 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002256 """
2257 Description:
2258 Obtain Bandwidth Allocation Information from ONOS cli.
2259 """
2260 try:
2261 cmdStr = "allocations"
2262 if jsonFormat:
2263 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002264 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002265 assert handle is not None, "Error in sendline"
2266 assert "Command not found:" not in handle, handle
2267 return handle
2268 except AssertionError:
2269 main.log.exception( "" )
2270 return None
2271 except ( TypeError, ValueError ):
2272 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2273 return None
2274 except pexpect.EOF:
2275 main.log.error( self.name + ": EOF exception found" )
2276 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002277 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002278 except Exception:
2279 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002280 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002281
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002282 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002283 """
andrewonlabe6745342014-10-17 14:29:13 -04002284 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002285 Obtain intents from the ONOS cli.
2286 Optional:
2287 * jsonFormat: Enable output formatting in json, default to True
2288 * summary: Whether only output the intent summary, defaults to False
2289 * type: Only output a certain type of intent. This options is valid
2290 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002291 """
andrewonlabe6745342014-10-17 14:29:13 -04002292 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002293 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002294 if summary:
2295 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002296 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002297 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002298 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002299 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002300 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002301 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002302 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002303 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002304 else:
Jon Hallff566d52016-01-15 14:45:36 -08002305 intentType = ""
2306 # IF we want the summary of a specific intent type
2307 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002308 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002309 if intentType in jsonResult.keys():
2310 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002311 else:
Jon Hallff566d52016-01-15 14:45:36 -08002312 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002313 return handle
2314 else:
2315 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002316 except AssertionError:
2317 main.log.exception( "" )
2318 return None
2319 except ( TypeError, ValueError ):
2320 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002321 return None
2322 except pexpect.EOF:
2323 main.log.error( self.name + ": EOF exception found" )
2324 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002325 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002326 except Exception:
2327 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002328 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002329
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002330 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002331 """
You Wangfdcbfc42016-05-16 12:16:53 -07002332 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002333 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002334 list of intent IDs.
2335 Parameters:
2336 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002337 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002338 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002339 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002340 accepted.
2341 Returns a list of dictionaries if a list of intent IDs is accepted,
2342 and each dictionary maps 'id' to the Intent ID and 'state' to
2343 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002344 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002345
kelvin-onlab54400a92015-02-26 18:05:51 -08002346 try:
2347 state = "State is Undefined"
2348 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002349 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002350 else:
Jon Hallc6793552016-01-19 14:18:37 -08002351 rawJson = intentsJson
2352 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002353 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002354 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002355 if intentsId == intent[ 'id' ]:
2356 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002357 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002358 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002359 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002360 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002361 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002362 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002363 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002364 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002365 for intent in parsedIntentsJson:
2366 if intentsId[ i ] == intent[ 'id' ]:
2367 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002368 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002369 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002370 break
Jon Hallefbd9792015-03-05 16:11:36 -08002371 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002372 main.log.warn( "Could not find all intents in ONOS output" )
2373 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002374 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002375 else:
Jon Hall53158082017-05-18 11:17:00 -07002376 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002377 return None
Jon Hallc6793552016-01-19 14:18:37 -08002378 except ( TypeError, ValueError ):
2379 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002380 return None
2381 except pexpect.EOF:
2382 main.log.error( self.name + ": EOF exception found" )
2383 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002384 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002385 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002386 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002387 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002388
Jon Hallf539eb92017-05-22 17:18:42 -07002389 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002390 """
2391 Description:
2392 Check intents state
2393 Required:
2394 intentsId - List of intents ID to be checked
2395 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002396 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002397 state in the list.
2398 *NOTE: You can pass in a list of expected state,
2399 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002400 Return:
Jon Hall53158082017-05-18 11:17:00 -07002401 Returns main.TRUE only if all intent are the same as expected states,
2402 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002403 """
2404 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002405 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002406 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002407
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002408 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002409 intentsDict = []
2410 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002411 if isinstance( intentsId, types.StringType ) \
2412 and intent.get( 'id' ) == intentsId:
2413 intentsDict.append( intent )
2414 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002415 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002416 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002417
2418 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002419 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002420 "getting intents state" )
2421 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002422
2423 if isinstance( expectedState, types.StringType ):
2424 for intents in intentsDict:
2425 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002426 main.log.debug( self.name + " : Intent ID - " +
2427 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002428 " actual state = " +
2429 intents.get( 'state' )
2430 + " does not equal expected state = "
2431 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002432 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002433 elif isinstance( expectedState, types.ListType ):
2434 for intents in intentsDict:
2435 if not any( state == intents.get( 'state' ) for state in
2436 expectedState ):
2437 main.log.debug( self.name + " : Intent ID - " +
2438 intents.get( 'id' ) +
2439 " actual state = " +
2440 intents.get( 'state' ) +
2441 " does not equal expected states = "
2442 + str( expectedState ) )
2443 returnValue = main.FALSE
2444
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002445 if returnValue == main.TRUE:
2446 main.log.info( self.name + ": All " +
2447 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002448 " intents are in " + str( expectedState ) +
2449 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002450 return returnValue
2451 except TypeError:
2452 main.log.exception( self.name + ": Object not as expected" )
2453 return None
2454 except pexpect.EOF:
2455 main.log.error( self.name + ": EOF exception found" )
2456 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002457 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002458 except Exception:
2459 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002460 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002461
Jon Hallf539eb92017-05-22 17:18:42 -07002462 def compareBandwidthAllocations( self, expectedAllocations ):
2463 """
2464 Description:
2465 Compare the allocated bandwidth with the given allocations
2466 Required:
2467 expectedAllocations - The expected ONOS output of the allocations command
2468 Return:
2469 Returns main.TRUE only if all intent are the same as expected states,
2470 otherwise returns main.FALSE.
2471 """
2472 # FIXME: Convert these string comparisons to object comparisons
2473 try:
2474 returnValue = main.TRUE
2475 bandwidthFailed = False
2476 rawAlloc = self.allocations()
2477 expectedFormat = StringIO( expectedAllocations )
2478 ONOSOutput = StringIO( rawAlloc )
2479 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2480 str( expectedFormat ) ) )
2481
2482 for actual, expected in izip( ONOSOutput, expectedFormat ):
2483 actual = actual.rstrip()
2484 expected = expected.rstrip()
2485 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2486 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002487 marker1 = actual.find( 'allocated' )
2488 m1 = actual[ :marker1 ]
2489 marker2 = expected.find( 'allocated' )
2490 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002491 if m1 != m2:
2492 bandwidthFailed = True
2493 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2494 bandwidthFailed = True
2495 expectedFormat.close()
2496 ONOSOutput.close()
2497
2498 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002499 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002500 returnValue = main.FALSE
2501 return returnValue
2502 except TypeError:
2503 main.log.exception( self.name + ": Object not as expected" )
2504 return None
2505 except pexpect.EOF:
2506 main.log.error( self.name + ": EOF exception found" )
2507 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002508 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002509 except Exception:
2510 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002511 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002512
You Wang66518af2016-05-16 15:32:59 -07002513 def compareIntent( self, intentDict ):
2514 """
2515 Description:
2516 Compare the intent ids and states provided in the argument with all intents in ONOS
2517 Return:
2518 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2519 Arguments:
2520 intentDict: a dictionary which maps intent ids to intent states
2521 """
2522 try:
2523 intentsRaw = self.intents()
2524 intentsJson = json.loads( intentsRaw )
2525 intentDictONOS = {}
2526 for intent in intentsJson:
2527 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002528 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002529 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002530 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002531 str( len( intentDict ) ) + " expected and " +
2532 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002533 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002534 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002535 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002536 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2537 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002538 else:
2539 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2540 main.log.debug( self.name + ": intent ID - " + intentID +
2541 " expected state is " + intentDict[ intentID ] +
2542 " but actual state is " + intentDictONOS[ intentID ] )
2543 returnValue = main.FALSE
2544 intentDictONOS.pop( intentID )
2545 if len( intentDictONOS ) > 0:
2546 returnValue = main.FALSE
2547 for intentID in intentDictONOS.keys():
2548 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002549 if returnValue == main.TRUE:
2550 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2551 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002552 except KeyError:
2553 main.log.exception( self.name + ": KeyError exception found" )
2554 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002555 except ( TypeError, ValueError ):
2556 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002557 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002558 except pexpect.EOF:
2559 main.log.error( self.name + ": EOF exception found" )
2560 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002561 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002562 except Exception:
2563 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002564 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002565
YPZhang14a4aa92016-07-15 13:37:15 -07002566 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002567 """
2568 Description:
2569 Check the number of installed intents.
2570 Optional:
2571 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002572 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002573 Return:
2574 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2575 , otherwise, returns main.FALSE.
2576 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002577
GlennRCed771242016-01-13 17:02:47 -08002578 try:
2579 cmd = "intents -s -j"
2580
2581 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002582 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002583 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002584 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002585 response = json.loads( response )
2586
2587 # get total and installed number, see if they are match
2588 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002589 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002590 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2591 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002592 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002593 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2594 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002595 return main.FALSE
2596
Jon Hallc6793552016-01-19 14:18:37 -08002597 except ( TypeError, ValueError ):
2598 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002599 return None
2600 except pexpect.EOF:
2601 main.log.error( self.name + ": EOF exception found" )
2602 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002603 if noExit:
2604 return main.FALSE
2605 else:
Devin Lim44075962017-08-11 10:56:37 -07002606 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002607 except pexpect.TIMEOUT:
2608 main.log.error( self.name + ": ONOS timeout" )
2609 return None
GlennRCed771242016-01-13 17:02:47 -08002610 except Exception:
2611 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002612 if noExit:
2613 return main.FALSE
2614 else:
Devin Lim44075962017-08-11 10:56:37 -07002615 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002616
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002617 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002618 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002619 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002620 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002621 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002622 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002623 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002624 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002625 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002626 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002627 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002628 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002629 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002630 cmdStr += " -n"
2631 cmdStr += " " + state
2632 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002633 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002634 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002635 assert "Command not found:" not in handle, handle
2636 if re.search( "Error:", handle ):
2637 main.log.error( self.name + ": flows() response: " +
2638 str( handle ) )
2639 return handle
2640 except AssertionError:
2641 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002642 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002643 except TypeError:
2644 main.log.exception( self.name + ": Object not as expected" )
2645 return None
Jon Hallc6793552016-01-19 14:18:37 -08002646 except pexpect.TIMEOUT:
2647 main.log.error( self.name + ": ONOS timeout" )
2648 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002649 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002650 main.log.error( self.name + ": EOF exception found" )
2651 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002652 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002653 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002654 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002655 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002656
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002657 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002658 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002659 count = int( count ) if count else 0
2660 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002661
Jon Halle0f0b342017-04-18 11:43:47 -07002662 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002663 """
2664 Description:
GlennRCed771242016-01-13 17:02:47 -08002665 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002666 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2667 if the count of those states is 0, which means all current flows
2668 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002669 Optional:
GlennRCed771242016-01-13 17:02:47 -08002670 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002671 Return:
2672 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002673 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002674 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002675 """
2676 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002677 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002678 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002679 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002680 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002681 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002682 if rawFlows:
2683 # if we didn't get flows or flows function return None, we should return
2684 # main.Flase
2685 checkedStates.append( json.loads( rawFlows ) )
2686 else:
2687 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002688 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002689 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002690 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002691 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002692 except TypeError:
2693 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002694 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002695
GlennRCed771242016-01-13 17:02:47 -08002696 # We want to count PENDING_ADD if isPENDING is true
2697 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002698 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002699 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002700 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002701 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002702 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002703 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002704 except ( TypeError, ValueError ):
2705 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002706 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002707
YPZhang240842b2016-05-17 12:00:50 -07002708 except AssertionError:
2709 main.log.exception( "" )
2710 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002711 except pexpect.TIMEOUT:
2712 main.log.error( self.name + ": ONOS timeout" )
2713 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002714 except pexpect.EOF:
2715 main.log.error( self.name + ": EOF exception found" )
2716 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002717 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002718 except Exception:
2719 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002720 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002721
GlennRCed771242016-01-13 17:02:47 -08002722 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002723 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002724 """
andrewonlab87852b02014-11-19 18:44:19 -05002725 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002726 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002727 a specific point-to-point intent definition
2728 Required:
GlennRCed771242016-01-13 17:02:47 -08002729 * ingress: specify source dpid
2730 * egress: specify destination dpid
2731 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002732 Optional:
GlennRCed771242016-01-13 17:02:47 -08002733 * offset: the keyOffset is where the next batch of intents
2734 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002735 * noExit: If set to True, TestON will not exit if any error when issus command
2736 * getResponse: If set to True, function will return ONOS response.
2737
GlennRCed771242016-01-13 17:02:47 -08002738 Returns: If failed to push test intents, it will returen None,
2739 if successful, return true.
2740 Timeout expection will return None,
2741 TypeError will return false
2742 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002743 """
andrewonlab87852b02014-11-19 18:44:19 -05002744 try:
GlennRCed771242016-01-13 17:02:47 -08002745 if background:
2746 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002747 else:
GlennRCed771242016-01-13 17:02:47 -08002748 back = ""
2749 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002750 ingress,
2751 egress,
2752 batchSize,
2753 offset,
2754 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002755 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002756 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002757 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002758 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002759 if getResponse:
2760 return response
2761
GlennRCed771242016-01-13 17:02:47 -08002762 # TODO: We should handle if there is failure in installation
2763 return main.TRUE
2764
Jon Hallc6793552016-01-19 14:18:37 -08002765 except AssertionError:
2766 main.log.exception( "" )
2767 return None
GlennRCed771242016-01-13 17:02:47 -08002768 except pexpect.TIMEOUT:
2769 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002770 return None
andrewonlab87852b02014-11-19 18:44:19 -05002771 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002772 main.log.error( self.name + ": EOF exception found" )
2773 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002774 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002775 except TypeError:
2776 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002777 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002778 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002779 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002780 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002781
YPZhangebf9eb52016-05-12 15:20:24 -07002782 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002783 """
2784 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002785 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002786 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002787 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002788 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002789 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002790
YPZhangb5d3f832016-01-23 22:54:26 -08002791 try:
YPZhange3109a72016-02-02 11:25:37 -08002792 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002793 cmd = "flows -c added"
2794 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2795 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002796 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002797 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002798 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002799 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002800 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002801 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002802 return None
2803 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002804
You Wangd3cb2ce2016-05-16 14:01:24 -07002805 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002806 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002807 return None
2808 except pexpect.EOF:
2809 main.log.error( self.name + ": EOF exception found" )
2810 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002811 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002812 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002813 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002814 except pexpect.TIMEOUT:
2815 main.log.error( self.name + ": ONOS timeout" )
2816 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002817 except Exception:
2818 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002819 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002820 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002821 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002822
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002823 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002824 """
2825 Description:
2826 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002827 Optional:
2828 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002829 Return:
2830 The number of intents
2831 """
2832 try:
2833 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002834 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002835 if response is None:
2836 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002837 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002838 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002839 except ( TypeError, ValueError ):
2840 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002841 return None
2842 except pexpect.EOF:
2843 main.log.error( self.name + ": EOF exception found" )
2844 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002845 if noExit:
2846 return -1
2847 else:
Devin Lim44075962017-08-11 10:56:37 -07002848 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002849 except Exception:
2850 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002851 if noExit:
2852 return -1
2853 else:
Devin Lim44075962017-08-11 10:56:37 -07002854 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002855
kelvin-onlabd3b64892015-01-20 13:26:24 -08002856 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002857 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002858 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002859 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002860 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002861 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002862 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002863 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002864 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002865 cmdStr += " -j"
2866 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002867 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002868 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002869 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002870 except AssertionError:
2871 main.log.exception( "" )
2872 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002873 except TypeError:
2874 main.log.exception( self.name + ": Object not as expected" )
2875 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002876 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002877 main.log.error( self.name + ": EOF exception found" )
2878 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002879 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002880 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002881 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002882 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002883
kelvin-onlabd3b64892015-01-20 13:26:24 -08002884 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002885 """
2886 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002887 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002888 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002889 """
andrewonlab867212a2014-10-22 20:13:38 -04002890 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002891 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002892 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002893 cmdStr += " -j"
2894 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002895 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002896 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002897 if handle:
2898 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002899 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002900 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002901 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002902 else:
2903 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002904 except AssertionError:
2905 main.log.exception( "" )
2906 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002907 except TypeError:
2908 main.log.exception( self.name + ": Object not as expected" )
2909 return None
andrewonlab867212a2014-10-22 20:13:38 -04002910 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002911 main.log.error( self.name + ": EOF exception found" )
2912 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002913 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002914 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002915 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002916 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002917
kelvin8ec71442015-01-15 16:57:00 -08002918 # Wrapper functions ****************
2919 # Wrapper functions use existing driver
2920 # functions and extends their use case.
2921 # For example, we may use the output of
2922 # a normal driver function, and parse it
2923 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002924
kelvin-onlabd3b64892015-01-20 13:26:24 -08002925 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002926 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002927 Description:
2928 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002929 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002930 try:
kelvin8ec71442015-01-15 16:57:00 -08002931 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002932 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002933 if intentsStr is None:
2934 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002935 # Convert to a dictionary
2936 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002937 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002938 for intent in intents:
2939 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002940 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002941 except TypeError:
2942 main.log.exception( self.name + ": Object not as expected" )
2943 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002944 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002945 main.log.error( self.name + ": EOF exception found" )
2946 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002947 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002948 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002949 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002950 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002951
You Wang3c276252016-09-21 15:21:36 -07002952 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002953 """
2954 Determine the number of flow rules for the given device id that are
2955 in the added state
You Wang3c276252016-09-21 15:21:36 -07002956 Params:
2957 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002958 """
2959 try:
You Wang3c276252016-09-21 15:21:36 -07002960 if core:
2961 cmdStr = "flows any " + str( deviceId ) + " | " +\
2962 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2963 else:
2964 cmdStr = "flows any " + str( deviceId ) + " | " +\
2965 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08002966 handle = self.lineCount( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002967 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002968 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002969 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002970 except AssertionError:
2971 main.log.exception( "" )
2972 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002973 except pexpect.EOF:
2974 main.log.error( self.name + ": EOF exception found" )
2975 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002976 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002977 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002978 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002979 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002980
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002981 def groupAddedCount( self, deviceId, core=False ):
2982 """
2983 Determine the number of group rules for the given device id that are
2984 in the added state
2985 Params:
2986 core: if True, only return the number of core groups added
2987 """
2988 try:
2989 if core:
2990 cmdStr = "groups any " + str( deviceId ) + " | " +\
2991 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2992 else:
2993 cmdStr = "groups any " + str( deviceId ) + " | " +\
2994 "grep 'state=ADDED' | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08002995 handle = self.lineCount( cmdStr )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002996 assert handle is not None, "Error in sendline"
2997 assert "Command not found:" not in handle, handle
2998 return handle
2999 except AssertionError:
3000 main.log.exception( "" )
3001 return None
3002 except pexpect.EOF:
3003 main.log.error( self.name + ": EOF exception found" )
3004 main.log.error( self.name + ": " + self.handle.before )
3005 main.cleanAndExit()
3006 except Exception:
3007 main.log.exception( self.name + ": Uncaught exception!" )
3008 main.cleanAndExit()
3009
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003010 def addStaticRoute( self, subnet, intf):
3011 """
3012 Adds a static route to onos.
3013 Params:
3014 subnet: The subnet reaching through this route
3015 intf: The interface this route is reachable through
3016 """
3017 try:
3018 cmdStr = "route-add " + subnet + " " + intf
3019 handle = self.sendline( cmdStr )
3020 assert handle is not None, "Error in sendline"
3021 assert "Command not found:" not in handle, handle
3022 return handle
3023 except AssertionError:
3024 main.log.exception( "" )
3025 return None
3026 except pexpect.EOF:
3027 main.log.error( self.name + ": EOF exception found" )
3028 main.log.error( self.name + ": " + self.handle.before )
3029 main.cleanAndExit()
3030 except Exception:
3031 main.log.exception( self.name + ": Uncaught exception!" )
3032 main.cleanAndExit()
3033
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003034 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
3035 """
3036 Description:
3037 Check whether the number of groups for the given device id that
3038 are in ADDED state is bigger than minGroupCount.
3039 Required:
3040 * deviceId: device id to check the number of added group rules
3041 Optional:
3042 * minGroupCount: the number of groups to compare
3043 * core: if True, only check the number of core groups added
3044 * comparison: if 0, compare with greater than minFlowCount
3045 * if 1, compare with equal to minFlowCount
3046 Return:
3047 Returns the number of groups if it is bigger than minGroupCount,
3048 returns main.FALSE otherwise.
3049 """
3050 count = self.groupAddedCount( deviceId, core )
3051 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003052 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003053 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
3054
You Wangc02f3be2018-05-18 12:14:23 -07003055 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003056 """
3057 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07003058 deviceId: Id of the device from which we retrieve groups
3059 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003060 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003061 try:
You Wangc02f3be2018-05-18 12:14:23 -07003062 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
3063 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07003064 assert handle is not None, "Error in sendline"
3065 assert "Command not found:" not in handle, handle
3066 return handle
3067 except AssertionError:
3068 main.log.exception( "" )
3069 return None
3070 except TypeError:
3071 main.log.exception( self.name + ": Object not as expected" )
3072 return None
3073 except pexpect.EOF:
3074 main.log.error( self.name + ": EOF exception found" )
3075 main.log.error( self.name + ": " + self.handle.before )
3076 main.cleanAndExit()
3077 except Exception:
3078 main.log.exception( self.name + ": Uncaught exception!" )
3079 main.cleanAndExit()
3080
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003081 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003082 """
3083 Description:
3084 Check whether the number of flow rules for the given device id that
3085 are in ADDED state is bigger than minFlowCount.
3086 Required:
3087 * deviceId: device id to check the number of added flow rules
3088 Optional:
3089 * minFlowCount: the number of flow rules to compare
3090 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003091 * comparison: if 0, compare with greater than minFlowCount
3092 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003093 Return:
3094 Returns the number of flow rules if it is bigger than minFlowCount,
3095 returns main.FALSE otherwise.
3096 """
3097 count = self.flowAddedCount( deviceId, core )
3098 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003099 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003100 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003101
kelvin-onlabd3b64892015-01-20 13:26:24 -08003102 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003103 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003104 Use 'devices' function to obtain list of all devices
3105 and parse the result to obtain a list of all device
3106 id's. Returns this list. Returns empty list if no
3107 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003108 List is ordered sequentially
3109
andrewonlab3e15ead2014-10-15 14:21:34 -04003110 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003111 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003112 the ids. By obtaining the list of device ids on the fly,
3113 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003114 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003115 try:
kelvin8ec71442015-01-15 16:57:00 -08003116 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003117 devicesStr = self.devices( jsonFormat=False )
3118 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003119
kelvin-onlabd3b64892015-01-20 13:26:24 -08003120 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003121 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003122 return idList
kelvin8ec71442015-01-15 16:57:00 -08003123
3124 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003125 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003126 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003127 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003128 # Split list further into arguments before and after string
3129 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003130 # append to idList
3131 for arg in tempList:
3132 idList.append( arg.split( "id=" )[ 1 ] )
3133 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003134
Jon Halld4d4b372015-01-28 16:02:41 -08003135 except TypeError:
3136 main.log.exception( self.name + ": Object not as expected" )
3137 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003138 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003139 main.log.error( self.name + ": EOF exception found" )
3140 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003141 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003142 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003143 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003144 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003145
kelvin-onlabd3b64892015-01-20 13:26:24 -08003146 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003147 """
andrewonlab7c211572014-10-15 16:45:20 -04003148 Uses 'nodes' function to obtain list of all nodes
3149 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003150 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003151 Returns:
3152 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003153 """
andrewonlab7c211572014-10-15 16:45:20 -04003154 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003155 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003156 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003157 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003158 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003159 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003160 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003161 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003162 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003163 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003164 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003165 except ( TypeError, ValueError ):
3166 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003167 return None
andrewonlab7c211572014-10-15 16:45:20 -04003168 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003169 main.log.error( self.name + ": EOF exception found" )
3170 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003171 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003172 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003173 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003174 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003175
kelvin-onlabd3b64892015-01-20 13:26:24 -08003176 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003177 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003178 Return the first device from the devices api whose 'id' contains 'dpid'
3179 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003180 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003181 try:
kelvin8ec71442015-01-15 16:57:00 -08003182 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003183 return None
3184 else:
kelvin8ec71442015-01-15 16:57:00 -08003185 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003186 rawDevices = self.devices()
3187 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003188 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003189 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003190 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3191 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003192 return device
3193 return None
Jon Hallc6793552016-01-19 14:18:37 -08003194 except ( TypeError, ValueError ):
3195 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003196 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003197 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003198 main.log.error( self.name + ": EOF exception found" )
3199 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003200 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003201 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003202 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003203 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003204
You Wang24139872016-05-03 11:48:47 -07003205 def getTopology( self, topologyOutput ):
3206 """
3207 Definition:
3208 Loads a json topology output
3209 Return:
3210 topology = current ONOS topology
3211 """
3212 import json
3213 try:
3214 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003215 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003216 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003217 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003218 except ( TypeError, ValueError ):
3219 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3220 return None
You Wang24139872016-05-03 11:48:47 -07003221 except pexpect.EOF:
3222 main.log.error( self.name + ": EOF exception found" )
3223 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003224 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003225 except Exception:
3226 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003227 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003228
Pier6a0c4de2018-03-18 16:01:30 -07003229 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003230 """
Jon Hallefbd9792015-03-05 16:11:36 -08003231 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003232 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003233 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003234
Flavio Castro82ee2f62016-06-07 15:04:12 -07003235 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003236 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003237 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003238 logLevel = level to log to.
3239 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003240
Jon Hallefbd9792015-03-05 16:11:36 -08003241 Returns: main.TRUE if the number of switches and links are correct,
3242 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003243 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003244 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003245 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003246 try:
You Wang13310252016-07-31 10:56:14 -07003247 summary = self.summary()
3248 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003249 except ( TypeError, ValueError ):
3250 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3251 return main.ERROR
3252 try:
3253 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003254 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003255 return main.ERROR
3256 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003257 # Is the number of switches is what we expected
3258 devices = topology.get( 'devices', False )
3259 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003260 nodes = summary.get( 'nodes', False )
3261 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003262 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003263 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003264 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003265 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003266 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3267 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003268 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003269 output = output + "The number of links and switches match "\
3270 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003271 result = main.TRUE
3272 else:
You Wang24139872016-05-03 11:48:47 -07003273 output = output + \
3274 "The number of links and switches does not match " + \
3275 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003276 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003277 output = output + "\n ONOS sees %i devices" % int( devices )
3278 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003279 if int( numolink ) > 0:
3280 output = output + "and %i links " % int( links )
3281 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003282 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003283 output = output + "and %i controllers " % int( nodes )
3284 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003285 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003286 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003287 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003288 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003289 else:
You Wang24139872016-05-03 11:48:47 -07003290 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003291 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003292 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003293 main.log.error( self.name + ": EOF exception found" )
3294 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003295 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003296 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003297 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003298 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003299
kelvin-onlabd3b64892015-01-20 13:26:24 -08003300 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003301 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003302 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003303 deviceId must be the id of a device as seen in the onos devices command
3304 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003305 role must be either master, standby, or none
3306
Jon Halle3f39ff2015-01-13 11:50:53 -08003307 Returns:
3308 main.TRUE or main.FALSE based on argument verification and
3309 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003310 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003311 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003312 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003313 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003314 cmdStr = "device-role " +\
3315 str( deviceId ) + " " +\
3316 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003317 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003318 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003319 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003320 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003321 if re.search( "Error", handle ):
3322 # end color output to escape any colours
3323 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003324 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003325 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003326 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003327 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003328 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003329 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003330 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003331 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003332 except AssertionError:
3333 main.log.exception( "" )
3334 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003335 except TypeError:
3336 main.log.exception( self.name + ": Object not as expected" )
3337 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003338 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003339 main.log.error( self.name + ": EOF exception found" )
3340 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003341 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003342 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003343 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003344 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003345
kelvin-onlabd3b64892015-01-20 13:26:24 -08003346 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003347 """
Jon Hall0dd09952018-04-19 09:59:11 -07003348 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003349 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003350 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003351 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003352 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003353 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003354 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003355 cmdStr += " -j"
3356 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003357 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003358 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003359 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003360 except AssertionError:
3361 main.log.exception( "" )
3362 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003363 except TypeError:
3364 main.log.exception( self.name + ": Object not as expected" )
3365 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003366 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003367 main.log.error( self.name + ": EOF exception found" )
3368 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003369 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003370 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003371 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003372 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003373
kelvin-onlabd3b64892015-01-20 13:26:24 -08003374 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003375 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003376 CLI command to get the current leader for the Election test application
3377 NOTE: Requires installation of the onos-app-election feature
3378 Returns: Node IP of the leader if one exists
3379 None if none exists
3380 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003381 """
Jon Hall94fd0472014-12-08 11:52:42 -08003382 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003383 cmdStr = "election-test-leader"
3384 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003385 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003386 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003387 # Leader
3388 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003389 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003390 nodeSearch = re.search( leaderPattern, response )
3391 if nodeSearch:
3392 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003393 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003394 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003395 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003396 # no leader
3397 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003398 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003399 nullSearch = re.search( nullPattern, response )
3400 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003401 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003402 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003403 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003404 # error
Jon Hall0e240372018-05-02 11:21:57 -07003405 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003406 ": " + "unexpected response" )
3407 main.log.error( repr( response ) )
3408 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003409 except AssertionError:
3410 main.log.exception( "" )
3411 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003412 except TypeError:
3413 main.log.exception( self.name + ": Object not as expected" )
3414 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003415 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003416 main.log.error( self.name + ": EOF exception found" )
3417 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003418 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003419 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003420 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003421 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003422
kelvin-onlabd3b64892015-01-20 13:26:24 -08003423 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003424 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003425 CLI command to run for leadership of the Election test application.
3426 NOTE: Requires installation of the onos-app-election feature
3427 Returns: Main.TRUE on success
3428 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003429 """
Jon Hall94fd0472014-12-08 11:52:42 -08003430 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003431 cmdStr = "election-test-run"
3432 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003433 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003434 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003435 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003436 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003437 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003438 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003439 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003440 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003441 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003442 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003443 # error
Jon Hall0e240372018-05-02 11:21:57 -07003444 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003445 ": " + "unexpected response" )
3446 main.log.error( repr( response ) )
3447 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003448 except AssertionError:
3449 main.log.exception( "" )
3450 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003451 except TypeError:
3452 main.log.exception( self.name + ": Object not as expected" )
3453 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003454 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003455 main.log.error( self.name + ": EOF exception found" )
3456 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003457 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003458 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003459 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003460 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003461
kelvin-onlabd3b64892015-01-20 13:26:24 -08003462 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003463 """
Jon Hall94fd0472014-12-08 11:52:42 -08003464 * CLI command to withdraw the local node from leadership election for
3465 * the Election test application.
3466 #NOTE: Requires installation of the onos-app-election feature
3467 Returns: Main.TRUE on success
3468 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003469 """
Jon Hall94fd0472014-12-08 11:52:42 -08003470 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003471 cmdStr = "election-test-withdraw"
3472 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003473 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003474 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003475 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003476 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003477 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003478 if re.search( successPattern, response ):
3479 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003480 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003481 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003482 # error
Jon Hall0e240372018-05-02 11:21:57 -07003483 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003484 self.name + ": " + "unexpected response" )
3485 main.log.error( repr( response ) )
3486 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003487 except AssertionError:
3488 main.log.exception( "" )
3489 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003490 except TypeError:
3491 main.log.exception( self.name + ": Object not as expected" )
3492 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003493 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003494 main.log.error( self.name + ": EOF exception found" )
3495 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003496 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003497 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003498 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003499 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003500
kelvin8ec71442015-01-15 16:57:00 -08003501 def getDevicePortsEnabledCount( self, dpid ):
3502 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003503 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003504 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003505 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003506 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003507 cmdStr = "onos:ports -e " + dpid + " | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003508 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003509 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003510 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003511 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003512 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003513 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003514 return output
Jon Hallc6793552016-01-19 14:18:37 -08003515 except AssertionError:
3516 main.log.exception( "" )
3517 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003518 except TypeError:
3519 main.log.exception( self.name + ": Object not as expected" )
3520 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003521 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003522 main.log.error( self.name + ": EOF exception found" )
3523 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003524 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003525 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003526 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003527 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003528
kelvin8ec71442015-01-15 16:57:00 -08003529 def getDeviceLinksActiveCount( self, dpid ):
3530 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003531 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003532 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003533 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003534 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003535 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
Jon Halld5a94fb2018-11-13 14:32:23 -08003536 output = self.lineCount( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003537 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003538 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003539 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003540 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003541 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003542 return output
Jon Hallc6793552016-01-19 14:18:37 -08003543 except AssertionError:
3544 main.log.exception( "" )
3545 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003546 except TypeError:
3547 main.log.exception( self.name + ": Object not as expected" )
3548 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003549 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003550 main.log.error( self.name + ": EOF exception found" )
3551 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003552 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003553 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003554 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003555 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003556
kelvin8ec71442015-01-15 16:57:00 -08003557 def getAllIntentIds( self ):
3558 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003559 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003560 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003561 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003562 cmdStr = "onos:intents | grep id="
3563 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003564 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003565 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003566 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003567 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003568 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003569 return output
Jon Hallc6793552016-01-19 14:18:37 -08003570 except AssertionError:
3571 main.log.exception( "" )
3572 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003573 except TypeError:
3574 main.log.exception( self.name + ": Object not as expected" )
3575 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003576 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003577 main.log.error( self.name + ": EOF exception found" )
3578 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003579 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003580 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003581 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003582 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003583
Jon Hall73509952015-02-24 16:42:56 -08003584 def intentSummary( self ):
3585 """
Jon Hallefbd9792015-03-05 16:11:36 -08003586 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003587 """
3588 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003589 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003590 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003591 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003592 states.append( intent.get( 'state', None ) )
3593 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003594 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003595 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003596 except ( TypeError, ValueError ):
3597 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003598 return None
3599 except pexpect.EOF:
3600 main.log.error( self.name + ": EOF exception found" )
3601 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003602 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003603 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003604 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003605 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003606
Jon Hall61282e32015-03-19 11:34:11 -07003607 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003608 """
3609 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003610 Optional argument:
3611 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003612 """
Jon Hall63604932015-02-26 17:09:50 -08003613 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003614 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003615 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003616 cmdStr += " -j"
3617 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003618 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003619 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003620 return output
Jon Hallc6793552016-01-19 14:18:37 -08003621 except AssertionError:
3622 main.log.exception( "" )
3623 return None
Jon Hall63604932015-02-26 17:09:50 -08003624 except TypeError:
3625 main.log.exception( self.name + ": Object not as expected" )
3626 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003627 except pexpect.EOF:
3628 main.log.error( self.name + ": EOF exception found" )
3629 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003630 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003631 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003632 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003633 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003634
acsmarsa4a4d1e2015-07-10 16:01:24 -07003635 def leaderCandidates( self, jsonFormat=True ):
3636 """
3637 Returns the output of the leaders -c command.
3638 Optional argument:
3639 * jsonFormat - boolean indicating if you want output in json
3640 """
3641 try:
3642 cmdStr = "onos:leaders -c"
3643 if jsonFormat:
3644 cmdStr += " -j"
3645 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003646 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003647 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003648 return output
Jon Hallc6793552016-01-19 14:18:37 -08003649 except AssertionError:
3650 main.log.exception( "" )
3651 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003652 except TypeError:
3653 main.log.exception( self.name + ": Object not as expected" )
3654 return None
3655 except pexpect.EOF:
3656 main.log.error( self.name + ": EOF exception found" )
3657 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003658 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003659 except Exception:
3660 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003661 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003662
Jon Hallc6793552016-01-19 14:18:37 -08003663 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003664 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003665 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003666 topic parameter and an empty list if the topic doesn't exist
3667 If no leader is elected leader in the returned list will be "none"
3668 Returns None if there is a type error processing the json object
3669 """
3670 try:
Jon Hall6e709752016-02-01 13:38:46 -08003671 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003672 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003673 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003674 assert "Command not found:" not in rawOutput, rawOutput
3675 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003676 results = []
3677 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003678 if dict[ "topic" ] == topic:
3679 leader = dict[ "leader" ]
3680 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003681 results.append( leader )
3682 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003683 return results
Jon Hallc6793552016-01-19 14:18:37 -08003684 except AssertionError:
3685 main.log.exception( "" )
3686 return None
3687 except ( TypeError, ValueError ):
3688 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003689 return None
3690 except pexpect.EOF:
3691 main.log.error( self.name + ": EOF exception found" )
3692 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003693 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003694 except Exception:
3695 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003696 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003697
Jon Hall61282e32015-03-19 11:34:11 -07003698 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003699 """
3700 Returns the output of the intent Pending map.
3701 """
Jon Hall63604932015-02-26 17:09:50 -08003702 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003703 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003704 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003705 cmdStr += " -j"
3706 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003707 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003708 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003709 return output
Jon Hallc6793552016-01-19 14:18:37 -08003710 except AssertionError:
3711 main.log.exception( "" )
3712 return None
Jon Hall63604932015-02-26 17:09:50 -08003713 except TypeError:
3714 main.log.exception( self.name + ": Object not as expected" )
3715 return None
3716 except pexpect.EOF:
3717 main.log.error( self.name + ": EOF exception found" )
3718 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003719 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003720 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003721 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003722 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003723
Jon Hall2c8959e2016-12-16 12:17:34 -08003724 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003725 """
3726 Returns the output of the raft partitions command for ONOS.
3727 """
Jon Hall61282e32015-03-19 11:34:11 -07003728 # Sample JSON
3729 # {
3730 # "leader": "tcp://10.128.30.11:7238",
3731 # "members": [
3732 # "tcp://10.128.30.11:7238",
3733 # "tcp://10.128.30.17:7238",
3734 # "tcp://10.128.30.13:7238",
3735 # ],
3736 # "name": "p1",
3737 # "term": 3
3738 # },
Jon Hall63604932015-02-26 17:09:50 -08003739 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003740 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003741 if candidates:
3742 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003743 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003744 cmdStr += " -j"
3745 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003746 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003747 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003748 return output
Jon Hallc6793552016-01-19 14:18:37 -08003749 except AssertionError:
3750 main.log.exception( "" )
3751 return None
Jon Hall63604932015-02-26 17:09:50 -08003752 except TypeError:
3753 main.log.exception( self.name + ": Object not as expected" )
3754 return None
3755 except pexpect.EOF:
3756 main.log.error( self.name + ": EOF exception found" )
3757 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003758 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003759 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003760 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003761 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003762
Jon Halle9f909e2016-09-23 10:43:12 -07003763 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003764 """
3765 Returns the output of the apps command for ONOS. This command lists
3766 information about installed ONOS applications
3767 """
3768 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003769 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003770 # "description":"ONOS OpenFlow protocol southbound providers",
3771 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003772 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003773 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003774 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003775 if summary:
3776 cmdStr += " -s"
3777 if active:
3778 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003779 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003780 cmdStr += " -j"
3781 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003782 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003783 assert "Command not found:" not in output, output
3784 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003785 return output
Jon Hallbe379602015-03-24 13:39:32 -07003786 # FIXME: look at specific exceptions/Errors
3787 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003788 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003789 return None
3790 except TypeError:
3791 main.log.exception( self.name + ": Object not as expected" )
3792 return None
3793 except pexpect.EOF:
3794 main.log.error( self.name + ": EOF exception found" )
3795 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003796 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003797 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003798 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003799 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003800
You Wangcdc51fe2018-08-12 17:14:56 -07003801 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003802 """
3803 Uses the onos:apps cli command to return the status of an application.
3804 Returns:
3805 "ACTIVE" - If app is installed and activated
3806 "INSTALLED" - If app is installed and deactivated
3807 "UNINSTALLED" - If app is not installed
3808 None - on error
3809 """
Jon Hall146f1522015-03-24 15:33:24 -07003810 try:
3811 if not isinstance( appName, types.StringType ):
3812 main.log.error( self.name + ".appStatus(): appName must be" +
3813 " a string" )
3814 return None
3815 output = self.apps( jsonFormat=True )
3816 appsJson = json.loads( output )
3817 state = None
3818 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003819 if appName == app.get( 'name' ):
3820 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003821 break
3822 if state == "ACTIVE" or state == "INSTALLED":
3823 return state
3824 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003825 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003826 return "UNINSTALLED"
3827 elif state:
3828 main.log.error( "Unexpected state from 'onos:apps': " +
3829 str( state ) )
3830 return state
Jon Hallc6793552016-01-19 14:18:37 -08003831 except ( TypeError, ValueError ):
3832 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003833 return None
3834 except pexpect.EOF:
3835 main.log.error( self.name + ": EOF exception found" )
3836 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003837 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003838 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003839 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003840 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003841
Jon Hallbe379602015-03-24 13:39:32 -07003842 def app( self, appName, option ):
3843 """
3844 Interacts with the app command for ONOS. This command manages
3845 application inventory.
3846 """
Jon Hallbe379602015-03-24 13:39:32 -07003847 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003848 # Validate argument types
3849 valid = True
3850 if not isinstance( appName, types.StringType ):
3851 main.log.error( self.name + ".app(): appName must be a " +
3852 "string" )
3853 valid = False
3854 if not isinstance( option, types.StringType ):
3855 main.log.error( self.name + ".app(): option must be a string" )
3856 valid = False
3857 if not valid:
3858 return main.FALSE
3859 # Validate Option
3860 option = option.lower()
3861 # NOTE: Install may become a valid option
3862 if option == "activate":
3863 pass
3864 elif option == "deactivate":
3865 pass
3866 elif option == "uninstall":
3867 pass
3868 else:
3869 # Invalid option
3870 main.log.error( "The ONOS app command argument only takes " +
3871 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003872 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003873 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003874 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003875 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003876 assert output is not None, "Error in sendline"
3877 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003878 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003879 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003880 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003881 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003882 elif "No such application" in output:
3883 main.log.error( "The application '" + appName +
3884 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003885 return main.FALSE
3886 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003887 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003888 str( output ) )
3889 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003890 elif "Unsupported command:" in output:
3891 main.log.error( "Incorrect command given to 'app': " +
3892 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003893 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003894 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003895 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003896 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003897 except AssertionError:
3898 main.log.exception( self.name + ": AssertionError exception found" )
3899 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003900 except TypeError:
3901 main.log.exception( self.name + ": Object not as expected" )
3902 return main.ERROR
3903 except pexpect.EOF:
3904 main.log.error( self.name + ": EOF exception found" )
3905 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003906 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003907 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003908 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003909 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003910
Jon Hallbd16b922015-03-26 17:53:15 -07003911 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003912 """
3913 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003914 appName is the hierarchical app name, not the feature name
3915 If check is True, method will check the status of the app after the
3916 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003917 Returns main.TRUE if the command was successfully sent
3918 main.FALSE if the cli responded with an error or given
3919 incorrect input
3920 """
3921 try:
3922 if not isinstance( appName, types.StringType ):
3923 main.log.error( self.name + ".activateApp(): appName must be" +
3924 " a string" )
3925 return main.FALSE
3926 status = self.appStatus( appName )
3927 if status == "INSTALLED":
3928 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003929 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003930 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003931 status = self.appStatus( appName )
3932 if status == "ACTIVE":
3933 return main.TRUE
3934 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003935 main.log.debug( "The state of application " +
3936 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003937 time.sleep( 1 )
3938 return main.FALSE
3939 else: # not 'check' or command didn't succeed
3940 return response
Jon Hall146f1522015-03-24 15:33:24 -07003941 elif status == "ACTIVE":
3942 return main.TRUE
3943 elif status == "UNINSTALLED":
3944 main.log.error( self.name + ": Tried to activate the " +
3945 "application '" + appName + "' which is not " +
3946 "installed." )
3947 else:
3948 main.log.error( "Unexpected return value from appStatus: " +
3949 str( status ) )
3950 return main.ERROR
3951 except TypeError:
3952 main.log.exception( self.name + ": Object not as expected" )
3953 return main.ERROR
3954 except pexpect.EOF:
3955 main.log.error( self.name + ": EOF exception found" )
3956 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003957 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003958 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003959 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003960 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003961
Jon Hallbd16b922015-03-26 17:53:15 -07003962 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003963 """
3964 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003965 appName is the hierarchical app name, not the feature name
3966 If check is True, method will check the status of the app after the
3967 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003968 Returns main.TRUE if the command was successfully sent
3969 main.FALSE if the cli responded with an error or given
3970 incorrect input
3971 """
3972 try:
3973 if not isinstance( appName, types.StringType ):
3974 main.log.error( self.name + ".deactivateApp(): appName must " +
3975 "be a string" )
3976 return main.FALSE
3977 status = self.appStatus( appName )
3978 if status == "INSTALLED":
3979 return main.TRUE
3980 elif status == "ACTIVE":
3981 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003982 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003983 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003984 status = self.appStatus( appName )
3985 if status == "INSTALLED":
3986 return main.TRUE
3987 else:
3988 time.sleep( 1 )
3989 return main.FALSE
3990 else: # not check or command didn't succeed
3991 return response
Jon Hall146f1522015-03-24 15:33:24 -07003992 elif status == "UNINSTALLED":
3993 main.log.warn( self.name + ": Tried to deactivate the " +
3994 "application '" + appName + "' which is not " +
3995 "installed." )
3996 return main.TRUE
3997 else:
3998 main.log.error( "Unexpected return value from appStatus: " +
3999 str( status ) )
4000 return main.ERROR
4001 except TypeError:
4002 main.log.exception( self.name + ": Object not as expected" )
4003 return main.ERROR
4004 except pexpect.EOF:
4005 main.log.error( self.name + ": EOF exception found" )
4006 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004007 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004008 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004009 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004010 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07004011
Jon Hallbd16b922015-03-26 17:53:15 -07004012 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07004013 """
4014 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07004015 appName is the hierarchical app name, not the feature name
4016 If check is True, method will check the status of the app after the
4017 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07004018 Returns main.TRUE if the command was successfully sent
4019 main.FALSE if the cli responded with an error or given
4020 incorrect input
4021 """
4022 # TODO: check with Thomas about the state machine for apps
4023 try:
4024 if not isinstance( appName, types.StringType ):
4025 main.log.error( self.name + ".uninstallApp(): appName must " +
4026 "be a string" )
4027 return main.FALSE
4028 status = self.appStatus( appName )
4029 if status == "INSTALLED":
4030 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004031 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004032 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004033 status = self.appStatus( appName )
4034 if status == "UNINSTALLED":
4035 return main.TRUE
4036 else:
4037 time.sleep( 1 )
4038 return main.FALSE
4039 else: # not check or command didn't succeed
4040 return response
Jon Hall146f1522015-03-24 15:33:24 -07004041 elif status == "ACTIVE":
4042 main.log.warn( self.name + ": Tried to uninstall the " +
4043 "application '" + appName + "' which is " +
4044 "currently active." )
4045 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07004046 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004047 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07004048 status = self.appStatus( appName )
4049 if status == "UNINSTALLED":
4050 return main.TRUE
4051 else:
4052 time.sleep( 1 )
4053 return main.FALSE
4054 else: # not check or command didn't succeed
4055 return response
Jon Hall146f1522015-03-24 15:33:24 -07004056 elif status == "UNINSTALLED":
4057 return main.TRUE
4058 else:
4059 main.log.error( "Unexpected return value from appStatus: " +
4060 str( status ) )
4061 return main.ERROR
4062 except TypeError:
4063 main.log.exception( self.name + ": Object not as expected" )
4064 return main.ERROR
4065 except pexpect.EOF:
4066 main.log.error( self.name + ": EOF exception found" )
4067 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004068 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004069 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004070 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004071 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004072
4073 def appIDs( self, jsonFormat=True ):
4074 """
4075 Show the mappings between app id and app names given by the 'app-ids'
4076 cli command
4077 """
4078 try:
4079 cmdStr = "app-ids"
4080 if jsonFormat:
4081 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004082 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004083 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004084 assert "Command not found:" not in output, output
4085 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004086 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004087 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004088 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004089 return None
4090 except TypeError:
4091 main.log.exception( self.name + ": Object not as expected" )
4092 return None
4093 except pexpect.EOF:
4094 main.log.error( self.name + ": EOF exception found" )
4095 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004096 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004097 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004098 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004099 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004100
4101 def appToIDCheck( self ):
4102 """
4103 This method will check that each application's ID listed in 'apps' is
4104 the same as the ID listed in 'app-ids'. The check will also check that
4105 there are no duplicate IDs issued. Note that an app ID should be
4106 a globaly unique numerical identifier for app/app-like features. Once
4107 an ID is registered, the ID is never freed up so that if an app is
4108 reinstalled it will have the same ID.
4109
4110 Returns: main.TRUE if the check passes and
4111 main.FALSE if the check fails or
4112 main.ERROR if there is some error in processing the test
4113 """
4114 try:
Jon Hall0e240372018-05-02 11:21:57 -07004115 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004116 rawJson = self.appIDs( jsonFormat=True )
4117 if rawJson:
4118 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004119 else:
Jon Hall0e240372018-05-02 11:21:57 -07004120 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4121 return main.FALSE
4122
4123 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004124 rawJson = self.apps( jsonFormat=True )
4125 if rawJson:
4126 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004127 else:
Jon Hallc6793552016-01-19 14:18:37 -08004128 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004129 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004130
Jon Hallbd16b922015-03-26 17:53:15 -07004131 result = main.TRUE
4132 for app in apps:
4133 appID = app.get( 'id' )
4134 if appID is None:
4135 main.log.error( "Error parsing app: " + str( app ) )
4136 result = main.FALSE
4137 appName = app.get( 'name' )
4138 if appName is None:
4139 main.log.error( "Error parsing app: " + str( app ) )
4140 result = main.FALSE
4141 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004142 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004143 if not current: # if ids doesn't have this id
4144 result = main.FALSE
4145 main.log.error( "'app-ids' does not have the ID for " +
4146 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004147 main.log.debug( "apps command returned: " + str( app ) +
4148 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004149 elif len( current ) > 1:
4150 # there is more than one app with this ID
4151 result = main.FALSE
4152 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004153 elif not current[ 0 ][ 'name' ] == appName:
4154 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004155 result = main.FALSE
4156 main.log.error( "'app-ids' has " + str( currentName ) +
4157 " registered under id:" + str( appID ) +
4158 " but 'apps' has " + str( appName ) )
4159 else:
4160 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004161
Jon Hallbd16b922015-03-26 17:53:15 -07004162 # now make sure that app-ids has no duplicates
4163 idsList = []
4164 namesList = []
4165 for item in ids:
4166 idsList.append( item[ 'id' ] )
4167 namesList.append( item[ 'name' ] )
4168 if len( idsList ) != len( set( idsList ) ) or\
4169 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004170 main.log.error( "'app-ids' has some duplicate entries: \n"
4171 + json.dumps( ids,
4172 sort_keys=True,
4173 indent=4,
4174 separators=( ',', ': ' ) ) )
4175 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004176 return result
Jon Hallc6793552016-01-19 14:18:37 -08004177 except ( TypeError, ValueError ):
4178 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004179 return main.ERROR
4180 except pexpect.EOF:
4181 main.log.error( self.name + ": EOF exception found" )
4182 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004183 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004184 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004185 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004186 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004187
Jon Hallfb760a02015-04-13 15:35:03 -07004188 def getCfg( self, component=None, propName=None, short=False,
4189 jsonFormat=True ):
4190 """
4191 Get configuration settings from onos cli
4192 Optional arguments:
4193 component - Optionally only list configurations for a specific
4194 component. If None, all components with configurations
4195 are displayed. Case Sensitive string.
4196 propName - If component is specified, propName option will show
4197 only this specific configuration from that component.
4198 Case Sensitive string.
4199 jsonFormat - Returns output as json. Note that this will override
4200 the short option
4201 short - Short, less verbose, version of configurations.
4202 This is overridden by the json option
4203 returns:
4204 Output from cli as a string or None on error
4205 """
4206 try:
4207 baseStr = "cfg"
4208 cmdStr = " get"
4209 componentStr = ""
4210 if component:
4211 componentStr += " " + component
4212 if propName:
4213 componentStr += " " + propName
4214 if jsonFormat:
4215 baseStr += " -j"
4216 elif short:
4217 baseStr += " -s"
4218 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004219 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004220 assert "Command not found:" not in output, output
4221 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004222 return output
4223 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004224 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004225 return None
4226 except TypeError:
4227 main.log.exception( self.name + ": Object not as expected" )
4228 return None
4229 except pexpect.EOF:
4230 main.log.error( self.name + ": EOF exception found" )
4231 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004232 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004233 except Exception:
4234 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004235 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004236
4237 def setCfg( self, component, propName, value=None, check=True ):
4238 """
4239 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004240 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004241 component - The case sensitive name of the component whose
4242 property is to be set
4243 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004244 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004245 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004246 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004247 check - Boolean, Check whether the option was successfully set this
4248 only applies when a value is given.
4249 returns:
4250 main.TRUE on success or main.FALSE on failure. If check is False,
4251 will return main.TRUE unless there is an error
4252 """
4253 try:
4254 baseStr = "cfg"
4255 cmdStr = " set " + str( component ) + " " + str( propName )
4256 if value is not None:
4257 cmdStr += " " + str( value )
4258 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004259 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004260 assert "Command not found:" not in output, output
4261 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004262 if value and check:
4263 results = self.getCfg( component=str( component ),
4264 propName=str( propName ),
4265 jsonFormat=True )
4266 # Check if current value is what we just set
4267 try:
4268 jsonOutput = json.loads( results )
4269 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004270 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004271 main.log.exception( "Error parsing cfg output" )
4272 main.log.error( "output:" + repr( results ) )
4273 return main.FALSE
4274 if current == str( value ):
4275 return main.TRUE
4276 return main.FALSE
4277 return main.TRUE
4278 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004279 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004280 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004281 except ( TypeError, ValueError ):
4282 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004283 return main.FALSE
4284 except pexpect.EOF:
4285 main.log.error( self.name + ": EOF exception found" )
4286 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004287 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004288 except Exception:
4289 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004290 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004291
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004292 def distPrimitivesSend( self, cmd ):
4293 """
4294 Function to handle sending cli commands for the distributed primitives test app
4295
4296 This command will catch some exceptions and retry the command on some
4297 specific store exceptions.
4298
4299 Required arguments:
4300 cmd - The command to send to the cli
4301 returns:
4302 string containing the cli output
4303 None on Error
4304 """
4305 try:
4306 output = self.sendline( cmd )
4307 try:
4308 assert output is not None, "Error in sendline"
4309 # TODO: Maybe make this less hardcoded
4310 # ConsistentMap Exceptions
4311 assert "org.onosproject.store.service" not in output
4312 # Node not leader
4313 assert "java.lang.IllegalStateException" not in output
4314 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004315 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004316 "command: " + str( output ) )
4317 retryTime = 30 # Conservative time, given by Madan
4318 main.log.info( "Waiting " + str( retryTime ) +
4319 "seconds before retrying." )
4320 time.sleep( retryTime ) # Due to change in mastership
4321 output = self.sendline( cmd )
4322 assert output is not None, "Error in sendline"
4323 assert "Command not found:" not in output, output
4324 assert "Error executing command" not in output, output
4325 main.log.info( self.name + ": " + output )
4326 return output
4327 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004328 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004329 return None
4330 except TypeError:
4331 main.log.exception( self.name + ": Object not as expected" )
4332 return None
4333 except pexpect.EOF:
4334 main.log.error( self.name + ": EOF exception found" )
4335 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004336 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004337 except Exception:
4338 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004339 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004340
Jon Hall390696c2015-05-05 17:13:41 -07004341 def setTestAdd( self, setName, values ):
4342 """
4343 CLI command to add elements to a distributed set.
4344 Arguments:
4345 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004346 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004347 Example usages:
4348 setTestAdd( "set1", "a b c" )
4349 setTestAdd( "set2", "1" )
4350 returns:
4351 main.TRUE on success OR
4352 main.FALSE if elements were already in the set OR
4353 main.ERROR on error
4354 """
4355 try:
4356 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004357 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004358 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4359 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004360 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004361 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004362 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004363 return main.FALSE
4364 else:
4365 main.log.error( self.name + ": setTestAdd did not" +
4366 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004367 main.log.debug( self.name + " actual: " + repr( output ) )
4368 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004369 except TypeError:
4370 main.log.exception( self.name + ": Object not as expected" )
4371 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004372 except Exception:
4373 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004374 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004375
4376 def setTestRemove( self, setName, values, clear=False, retain=False ):
4377 """
4378 CLI command to remove elements from a distributed set.
4379 Required arguments:
4380 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004381 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004382 Optional arguments:
4383 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004384 retain - Retain only the given values. (intersection of the
4385 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004386 returns:
4387 main.TRUE on success OR
4388 main.FALSE if the set was not changed OR
4389 main.ERROR on error
4390 """
4391 try:
4392 cmdStr = "set-test-remove "
4393 if clear:
4394 cmdStr += "-c " + str( setName )
4395 elif retain:
4396 cmdStr += "-r " + str( setName ) + " " + str( values )
4397 else:
4398 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004399 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004400 if clear:
4401 pattern = "Set " + str( setName ) + " cleared"
4402 if re.search( pattern, output ):
4403 return main.TRUE
4404 elif retain:
4405 positivePattern = str( setName ) + " was pruned to contain " +\
4406 "only elements of set \[(.*)\]"
4407 negativePattern = str( setName ) + " was not changed by " +\
4408 "retaining only elements of the set " +\
4409 "\[(.*)\]"
4410 if re.search( positivePattern, output ):
4411 return main.TRUE
4412 elif re.search( negativePattern, output ):
4413 return main.FALSE
4414 else:
4415 positivePattern = "\[(.*)\] was removed from the set " +\
4416 str( setName )
4417 if ( len( values.split() ) == 1 ):
4418 negativePattern = "\[(.*)\] was not in set " +\
4419 str( setName )
4420 else:
4421 negativePattern = "No element of \[(.*)\] was in set " +\
4422 str( setName )
4423 if re.search( positivePattern, output ):
4424 return main.TRUE
4425 elif re.search( negativePattern, output ):
4426 return main.FALSE
4427 main.log.error( self.name + ": setTestRemove did not" +
4428 " match expected output" )
4429 main.log.debug( self.name + " expected: " + pattern )
4430 main.log.debug( self.name + " actual: " + repr( output ) )
4431 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004432 except TypeError:
4433 main.log.exception( self.name + ": Object not as expected" )
4434 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004435 except Exception:
4436 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004437 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004438
4439 def setTestGet( self, setName, values="" ):
4440 """
4441 CLI command to get the elements in a distributed set.
4442 Required arguments:
4443 setName - The name of the set to remove from.
4444 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004445 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004446 returns:
4447 main.ERROR on error OR
4448 A list of elements in the set if no optional arguments are
4449 supplied OR
4450 A tuple containing the list then:
4451 main.FALSE if the given values are not in the set OR
4452 main.TRUE if the given values are in the set OR
4453 """
4454 try:
4455 values = str( values ).strip()
4456 setName = str( setName ).strip()
4457 length = len( values.split() )
4458 containsCheck = None
4459 # Patterns to match
4460 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004461 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004462 containsTrue = "Set " + setName + " contains the value " + values
4463 containsFalse = "Set " + setName + " did not contain the value " +\
4464 values
4465 containsAllTrue = "Set " + setName + " contains the the subset " +\
4466 setPattern
4467 containsAllFalse = "Set " + setName + " did not contain the the" +\
4468 " subset " + setPattern
4469
4470 cmdStr = "set-test-get "
4471 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004472 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004473 if length == 0:
4474 match = re.search( pattern, output )
4475 else: # if given values
4476 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004477 patternTrue = pattern + "\r\n" + containsTrue
4478 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004479 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004480 patternTrue = pattern + "\r\n" + containsAllTrue
4481 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004482 matchTrue = re.search( patternTrue, output )
4483 matchFalse = re.search( patternFalse, output )
4484 if matchTrue:
4485 containsCheck = main.TRUE
4486 match = matchTrue
4487 elif matchFalse:
4488 containsCheck = main.FALSE
4489 match = matchFalse
4490 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004491 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004492 "expected output" )
4493 main.log.debug( self.name + " expected: " + pattern )
4494 main.log.debug( self.name + " actual: " + repr( output ) )
4495 match = None
4496 if match:
4497 setMatch = match.group( 1 )
4498 if setMatch == '':
4499 setList = []
4500 else:
4501 setList = setMatch.split( ", " )
4502 if length > 0:
4503 return ( setList, containsCheck )
4504 else:
4505 return setList
4506 else: # no match
4507 main.log.error( self.name + ": setTestGet did not" +
4508 " match expected output" )
4509 main.log.debug( self.name + " expected: " + pattern )
4510 main.log.debug( self.name + " actual: " + repr( output ) )
4511 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004512 except TypeError:
4513 main.log.exception( self.name + ": Object not as expected" )
4514 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004515 except Exception:
4516 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004517 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004518
4519 def setTestSize( self, setName ):
4520 """
4521 CLI command to get the elements in a distributed set.
4522 Required arguments:
4523 setName - The name of the set to remove from.
4524 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004525 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004526 None on error
4527 """
4528 try:
4529 # TODO: Should this check against the number of elements returned
4530 # and then return true/false based on that?
4531 setName = str( setName ).strip()
4532 # Patterns to match
4533 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004534 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004535 setPattern
4536 cmdStr = "set-test-get -s "
4537 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004538 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004539 if output:
4540 match = re.search( pattern, output )
4541 if match:
4542 setSize = int( match.group( 1 ) )
4543 setMatch = match.group( 2 )
4544 if len( setMatch.split() ) == setSize:
4545 main.log.info( "The size returned by " + self.name +
4546 " matches the number of elements in " +
4547 "the returned set" )
4548 else:
4549 main.log.error( "The size returned by " + self.name +
4550 " does not match the number of " +
4551 "elements in the returned set." )
4552 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004553 else: # no match
4554 main.log.error( self.name + ": setTestGet did not" +
4555 " match expected output" )
4556 main.log.debug( self.name + " expected: " + pattern )
4557 main.log.debug( self.name + " actual: " + repr( output ) )
4558 return None
Jon Hall390696c2015-05-05 17:13:41 -07004559 except TypeError:
4560 main.log.exception( self.name + ": Object not as expected" )
4561 return None
Jon Hall390696c2015-05-05 17:13:41 -07004562 except Exception:
4563 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004564 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004565
Jon Hall80daded2015-05-27 16:07:00 -07004566 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004567 """
4568 Command to list the various counters in the system.
4569 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004570 if jsonFormat, a string of the json object returned by the cli
4571 command
4572 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004573 None on error
4574 """
Jon Hall390696c2015-05-05 17:13:41 -07004575 try:
Jon Hall390696c2015-05-05 17:13:41 -07004576 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004577 if jsonFormat:
4578 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004579 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004580 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004581 assert "Command not found:" not in output, output
4582 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004583 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004584 return output
Jon Hall390696c2015-05-05 17:13:41 -07004585 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004586 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004587 return None
Jon Hall390696c2015-05-05 17:13:41 -07004588 except TypeError:
4589 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004590 return None
Jon Hall390696c2015-05-05 17:13:41 -07004591 except pexpect.EOF:
4592 main.log.error( self.name + ": EOF exception found" )
4593 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004594 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004595 except Exception:
4596 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004597 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004598
Jon Hall935db192016-04-19 00:22:04 -07004599 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004600 """
Jon Halle1a3b752015-07-22 13:02:46 -07004601 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004602 Required arguments:
4603 counter - The name of the counter to increment.
4604 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004605 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004606 returns:
4607 integer value of the counter or
4608 None on Error
4609 """
4610 try:
4611 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004612 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004613 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004614 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004615 if delta != 1:
4616 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004617 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004618 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004619 match = re.search( pattern, output )
4620 if match:
4621 return int( match.group( 1 ) )
4622 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004623 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004624 " match expected output." )
4625 main.log.debug( self.name + " expected: " + pattern )
4626 main.log.debug( self.name + " actual: " + repr( output ) )
4627 return None
Jon Hall390696c2015-05-05 17:13:41 -07004628 except TypeError:
4629 main.log.exception( self.name + ": Object not as expected" )
4630 return None
Jon Hall390696c2015-05-05 17:13:41 -07004631 except Exception:
4632 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004633 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004634
Jon Hall935db192016-04-19 00:22:04 -07004635 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004636 """
4637 CLI command to get a distributed counter then add a delta to it.
4638 Required arguments:
4639 counter - The name of the counter to increment.
4640 Optional arguments:
4641 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004642 returns:
4643 integer value of the counter or
4644 None on Error
4645 """
4646 try:
4647 counter = str( counter )
4648 delta = int( delta )
4649 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004650 cmdStr += counter
4651 if delta != 1:
4652 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004653 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004654 pattern = counter + " was updated to (-?\d+)"
4655 match = re.search( pattern, output )
4656 if match:
4657 return int( match.group( 1 ) )
4658 else:
4659 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4660 " match expected output." )
4661 main.log.debug( self.name + " expected: " + pattern )
4662 main.log.debug( self.name + " actual: " + repr( output ) )
4663 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004664 except TypeError:
4665 main.log.exception( self.name + ": Object not as expected" )
4666 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004667 except Exception:
4668 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004669 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004670
4671 def valueTestGet( self, valueName ):
4672 """
4673 CLI command to get the value of an atomic value.
4674 Required arguments:
4675 valueName - The name of the value to get.
4676 returns:
4677 string value of the value or
4678 None on Error
4679 """
4680 try:
4681 valueName = str( valueName )
4682 cmdStr = "value-test "
4683 operation = "get"
4684 cmdStr = "value-test {} {}".format( valueName,
4685 operation )
4686 output = self.distPrimitivesSend( cmdStr )
4687 pattern = "(\w+)"
4688 match = re.search( pattern, output )
4689 if match:
4690 return match.group( 1 )
4691 else:
4692 main.log.error( self.name + ": valueTestGet did not" +
4693 " match expected output." )
4694 main.log.debug( self.name + " expected: " + pattern )
4695 main.log.debug( self.name + " actual: " + repr( output ) )
4696 return None
4697 except TypeError:
4698 main.log.exception( self.name + ": Object not as expected" )
4699 return None
4700 except Exception:
4701 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004702 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004703
4704 def valueTestSet( self, valueName, newValue ):
4705 """
4706 CLI command to set the value of an atomic value.
4707 Required arguments:
4708 valueName - The name of the value to set.
4709 newValue - The value to assign to the given value.
4710 returns:
4711 main.TRUE on success or
4712 main.ERROR on Error
4713 """
4714 try:
4715 valueName = str( valueName )
4716 newValue = str( newValue )
4717 operation = "set"
4718 cmdStr = "value-test {} {} {}".format( valueName,
4719 operation,
4720 newValue )
4721 output = self.distPrimitivesSend( cmdStr )
4722 if output is not None:
4723 return main.TRUE
4724 else:
4725 return main.ERROR
4726 except TypeError:
4727 main.log.exception( self.name + ": Object not as expected" )
4728 return main.ERROR
4729 except Exception:
4730 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004731 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004732
4733 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4734 """
4735 CLI command to compareAndSet the value of an atomic value.
4736 Required arguments:
4737 valueName - The name of the value.
4738 oldValue - Compare the current value of the atomic value to this
4739 newValue - If the value equals oldValue, set the value to newValue
4740 returns:
4741 main.TRUE on success or
4742 main.FALSE on failure or
4743 main.ERROR on Error
4744 """
4745 try:
4746 valueName = str( valueName )
4747 oldValue = str( oldValue )
4748 newValue = str( newValue )
4749 operation = "compareAndSet"
4750 cmdStr = "value-test {} {} {} {}".format( valueName,
4751 operation,
4752 oldValue,
4753 newValue )
4754 output = self.distPrimitivesSend( cmdStr )
4755 pattern = "(\w+)"
4756 match = re.search( pattern, output )
4757 if match:
4758 result = match.group( 1 )
4759 if result == "true":
4760 return main.TRUE
4761 elif result == "false":
4762 return main.FALSE
4763 else:
4764 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4765 " match expected output." )
4766 main.log.debug( self.name + " expected: " + pattern )
4767 main.log.debug( self.name + " actual: " + repr( output ) )
4768 return main.ERROR
4769 except TypeError:
4770 main.log.exception( self.name + ": Object not as expected" )
4771 return main.ERROR
4772 except Exception:
4773 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004774 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004775
4776 def valueTestGetAndSet( self, valueName, newValue ):
4777 """
4778 CLI command to getAndSet the value of an atomic value.
4779 Required arguments:
4780 valueName - The name of the value to get.
4781 newValue - The value to assign to the given value
4782 returns:
4783 string value of the value or
4784 None on Error
4785 """
4786 try:
4787 valueName = str( valueName )
4788 cmdStr = "value-test "
4789 operation = "getAndSet"
4790 cmdStr += valueName + " " + operation
4791 cmdStr = "value-test {} {} {}".format( valueName,
4792 operation,
4793 newValue )
4794 output = self.distPrimitivesSend( cmdStr )
4795 pattern = "(\w+)"
4796 match = re.search( pattern, output )
4797 if match:
4798 return match.group( 1 )
4799 else:
4800 main.log.error( self.name + ": valueTestGetAndSet did not" +
4801 " match expected output." )
4802 main.log.debug( self.name + " expected: " + pattern )
4803 main.log.debug( self.name + " actual: " + repr( output ) )
4804 return None
4805 except TypeError:
4806 main.log.exception( self.name + ": Object not as expected" )
4807 return None
4808 except Exception:
4809 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004810 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004811
4812 def valueTestDestroy( self, valueName ):
4813 """
4814 CLI command to destroy an atomic value.
4815 Required arguments:
4816 valueName - The name of the value to destroy.
4817 returns:
4818 main.TRUE on success or
4819 main.ERROR on Error
4820 """
4821 try:
4822 valueName = str( valueName )
4823 cmdStr = "value-test "
4824 operation = "destroy"
4825 cmdStr += valueName + " " + operation
4826 output = self.distPrimitivesSend( cmdStr )
4827 if output is not None:
4828 return main.TRUE
4829 else:
4830 return main.ERROR
4831 except TypeError:
4832 main.log.exception( self.name + ": Object not as expected" )
4833 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004834 except Exception:
4835 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004836 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004837
YPZhangfebf7302016-05-24 16:45:56 -07004838 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004839 """
4840 Description: Execute summary command in onos
4841 Returns: json object ( summary -j ), returns main.FALSE if there is
4842 no output
4843
4844 """
4845 try:
4846 cmdStr = "summary"
4847 if jsonFormat:
4848 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004849 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004850 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004851 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004852 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004853 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004854 if not handle:
4855 main.log.error( self.name + ": There is no output in " +
4856 "summary command" )
4857 return main.FALSE
4858 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004859 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004860 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004861 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004862 except TypeError:
4863 main.log.exception( self.name + ": Object not as expected" )
4864 return None
4865 except pexpect.EOF:
4866 main.log.error( self.name + ": EOF exception found" )
4867 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004868 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004869 except Exception:
4870 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004871 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004872
Jon Hall935db192016-04-19 00:22:04 -07004873 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004874 """
4875 CLI command to get the value of a key in a consistent map using
4876 transactions. This a test function and can only get keys from the
4877 test map hard coded into the cli command
4878 Required arguments:
4879 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004880 returns:
4881 The string value of the key or
4882 None on Error
4883 """
4884 try:
4885 keyName = str( keyName )
4886 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004887 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004888 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004889 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4890 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004891 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004892 return None
4893 else:
4894 match = re.search( pattern, output )
4895 if match:
4896 return match.groupdict()[ 'value' ]
4897 else:
4898 main.log.error( self.name + ": transactionlMapGet did not" +
4899 " match expected output." )
4900 main.log.debug( self.name + " expected: " + pattern )
4901 main.log.debug( self.name + " actual: " + repr( output ) )
4902 return None
4903 except TypeError:
4904 main.log.exception( self.name + ": Object not as expected" )
4905 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004906 except Exception:
4907 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004908 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004909
Jon Hall935db192016-04-19 00:22:04 -07004910 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004911 """
4912 CLI command to put a value into 'numKeys' number of keys in a
4913 consistent map using transactions. This a test function and can only
4914 put into keys named 'Key#' of the test map hard coded into the cli command
4915 Required arguments:
4916 numKeys - Number of keys to add the value to
4917 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004918 returns:
4919 A dictionary whose keys are the name of the keys put into the map
4920 and the values of the keys are dictionaries whose key-values are
4921 'value': value put into map and optionaly
4922 'oldValue': Previous value in the key or
4923 None on Error
4924
4925 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004926 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4927 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004928 """
4929 try:
4930 numKeys = str( numKeys )
4931 value = str( value )
4932 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004933 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004934 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004935 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4936 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4937 results = {}
4938 for line in output.splitlines():
4939 new = re.search( newPattern, line )
4940 updated = re.search( updatedPattern, line )
4941 if new:
4942 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4943 elif updated:
4944 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004945 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004946 else:
4947 main.log.error( self.name + ": transactionlMapGet did not" +
4948 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004949 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4950 newPattern,
4951 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004952 main.log.debug( self.name + " actual: " + repr( output ) )
4953 return results
Jon Hall0e240372018-05-02 11:21:57 -07004954 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004955 main.log.exception( self.name + ": Object not as expected" )
4956 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004957 except Exception:
4958 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004959 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004960
acsmarsdaea66c2015-09-03 11:44:06 -07004961 def maps( self, jsonFormat=True ):
4962 """
4963 Description: Returns result of onos:maps
4964 Optional:
4965 * jsonFormat: enable json formatting of output
4966 """
4967 try:
4968 cmdStr = "maps"
4969 if jsonFormat:
4970 cmdStr += " -j"
4971 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004972 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004973 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004974 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004975 except AssertionError:
4976 main.log.exception( "" )
4977 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004978 except TypeError:
4979 main.log.exception( self.name + ": Object not as expected" )
4980 return None
4981 except pexpect.EOF:
4982 main.log.error( self.name + ": EOF exception found" )
4983 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004984 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004985 except Exception:
4986 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004987 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004988
4989 def getSwController( self, uri, jsonFormat=True ):
4990 """
4991 Descrition: Gets the controller information from the device
4992 """
4993 try:
4994 cmd = "device-controllers "
4995 if jsonFormat:
4996 cmd += "-j "
4997 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004998 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004999 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005000 return response
Jon Hallc6793552016-01-19 14:18:37 -08005001 except AssertionError:
5002 main.log.exception( "" )
5003 return None
GlennRC050596c2015-11-18 17:06:41 -08005004 except TypeError:
5005 main.log.exception( self.name + ": Object not as expected" )
5006 return None
5007 except pexpect.EOF:
5008 main.log.error( self.name + ": EOF exception found" )
5009 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005010 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005011 except Exception:
5012 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005013 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005014
5015 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
5016 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005017 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08005018
5019 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005020 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08005021 ip - String or List: The ip address of the controller.
5022 This parameter can be formed in a couple of different ways.
5023 VALID:
5024 10.0.0.1 - just the ip address
5025 tcp:10.0.0.1 - the protocol and the ip address
5026 tcp:10.0.0.1:6653 - the protocol and port can be specified,
5027 so that you can add controllers with different
5028 protocols and ports
5029 INVALID:
5030 10.0.0.1:6653 - this is not supported by ONOS
5031
5032 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
5033 port - The port number.
5034 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
5035
5036 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
5037 """
5038 try:
5039 cmd = "device-setcontrollers"
5040
5041 if jsonFormat:
5042 cmd += " -j"
5043 cmd += " " + uri
5044 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005045 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08005046 for item in ip:
5047 if ":" in item:
5048 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005049 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08005050 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005051 elif "." in sitem[ 1 ]:
5052 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08005053 else:
5054 main.log.error( "Malformed entry: " + item )
5055 raise TypeError
5056 else:
5057 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08005058 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07005059 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005060 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08005061 if "Error" in response:
5062 main.log.error( response )
5063 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005064 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005065 except AssertionError:
5066 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005067 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005068 except TypeError:
5069 main.log.exception( self.name + ": Object not as expected" )
5070 return main.FALSE
5071 except pexpect.EOF:
5072 main.log.error( self.name + ": EOF exception found" )
5073 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005074 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005075 except Exception:
5076 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005077 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005078
5079 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005080 '''
GlennRC20fc6522015-12-23 23:26:57 -08005081 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005082 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005083 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005084 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005085 Returns:
5086 Returns main.FALSE if an exception is thrown or an error is present
5087 in the response. Otherwise, returns main.TRUE.
5088 NOTE:
5089 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005090 '''
GlennRC20fc6522015-12-23 23:26:57 -08005091 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005092 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005093 deviceStr = device
5094 device = []
5095 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005096
5097 for d in device:
5098 time.sleep( 1 )
5099 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005100 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005101 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005102 if "Error" in response:
5103 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5104 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005105 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005106 except AssertionError:
5107 main.log.exception( "" )
5108 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005109 except TypeError:
5110 main.log.exception( self.name + ": Object not as expected" )
5111 return main.FALSE
5112 except pexpect.EOF:
5113 main.log.error( self.name + ": EOF exception found" )
5114 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005115 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005116 except Exception:
5117 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005118 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005119
5120 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005121 '''
GlennRC20fc6522015-12-23 23:26:57 -08005122 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005123 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005124 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005125 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005126 Returns:
5127 Returns main.FALSE if an exception is thrown or an error is present
5128 in the response. Otherwise, returns main.TRUE.
5129 NOTE:
5130 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005131 '''
GlennRC20fc6522015-12-23 23:26:57 -08005132 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005133 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005134 host = list( host )
5135
5136 for h in host:
5137 time.sleep( 1 )
5138 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005139 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005140 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005141 if "Error" in response:
5142 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5143 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005144 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005145 except AssertionError:
5146 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005147 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005148 except TypeError:
5149 main.log.exception( self.name + ": Object not as expected" )
5150 return main.FALSE
5151 except pexpect.EOF:
5152 main.log.error( self.name + ": EOF exception found" )
5153 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005154 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005155 except Exception:
5156 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005157 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005158
YPZhangfebf7302016-05-24 16:45:56 -07005159 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005160 '''
GlennRCed771242016-01-13 17:02:47 -08005161 Description:
5162 Bring link down or up in the null-provider.
5163 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005164 begin - (string) One end of a device or switch.
5165 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005166 returns:
5167 main.TRUE if no exceptions were thrown and no Errors are
5168 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005169 '''
GlennRCed771242016-01-13 17:02:47 -08005170 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005171 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005172 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005173 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005174 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005175 if "Error" in response or "Failure" in response:
5176 main.log.error( response )
5177 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005178 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005179 except AssertionError:
5180 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005181 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005182 except TypeError:
5183 main.log.exception( self.name + ": Object not as expected" )
5184 return main.FALSE
5185 except pexpect.EOF:
5186 main.log.error( self.name + ": EOF exception found" )
5187 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005188 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005189 except Exception:
5190 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005191 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005192
Jon Hall2c8959e2016-12-16 12:17:34 -08005193 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005194 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005195 Description:
5196 Changes the state of port in an OF switch by means of the
5197 PORTSTATUS OF messages.
5198 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005199 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5200 port - (string) target port in the device. Ex: '2'
5201 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005202 returns:
5203 main.TRUE if no exceptions were thrown and no Errors are
5204 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005205 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005206 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005207 state = state.lower()
5208 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005209 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005210 response = self.sendline( cmd, showResponse=True )
5211 assert response is not None, "Error in sendline"
5212 assert "Command not found:" not in response, response
5213 if "Error" in response or "Failure" in response:
5214 main.log.error( response )
5215 return main.FALSE
5216 return main.TRUE
5217 except AssertionError:
5218 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005219 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005220 except TypeError:
5221 main.log.exception( self.name + ": Object not as expected" )
5222 return main.FALSE
5223 except pexpect.EOF:
5224 main.log.error( self.name + ": EOF exception found" )
5225 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005226 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005227 except Exception:
5228 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005229 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005230
5231 def logSet( self, level="INFO", app="org.onosproject" ):
5232 """
5233 Set the logging level to lvl for a specific app
5234 returns main.TRUE on success
5235 returns main.FALSE if Error occurred
5236 if noExit is True, TestON will not exit, but clean up
5237 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5238 Level defaults to INFO
5239 """
5240 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005241 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Jon Hall6c9e2da2018-11-06 12:01:23 -08005242 self.handle.expect( self.karafPrompt )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005243
5244 response = self.handle.before
5245 if re.search( "Error", response ):
5246 return main.FALSE
5247 return main.TRUE
5248 except pexpect.TIMEOUT:
5249 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005250 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005251 except pexpect.EOF:
5252 main.log.error( self.name + ": EOF exception found" )
5253 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005254 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005255 except Exception:
5256 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005257 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005258
5259 def getGraphDict( self, timeout=60, includeHost=False ):
5260 """
5261 Return a dictionary which describes the latest network topology data as a
5262 graph.
5263 An example of the dictionary:
5264 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5265 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5266 Each vertex should at least have an 'edges' attribute which describes the
5267 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005268 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005269 list of attributes.
5270 An example of the edges dictionary:
5271 'edges': { vertex2: { 'port': ..., 'weight': ... },
5272 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005273 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005274 in topology data.
5275 """
5276 graphDict = {}
5277 try:
5278 links = self.links()
5279 links = json.loads( links )
5280 devices = self.devices()
5281 devices = json.loads( devices )
5282 idToDevice = {}
5283 for device in devices:
5284 idToDevice[ device[ 'id' ] ] = device
5285 if includeHost:
5286 hosts = self.hosts()
5287 # FIXME: support 'includeHost' argument
5288 for link in links:
5289 nodeA = link[ 'src' ][ 'device' ]
5290 nodeB = link[ 'dst' ][ 'device' ]
5291 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005292 if nodeA not in graphDict.keys():
5293 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005294 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005295 'type': idToDevice[ nodeA ][ 'type' ],
5296 'available': idToDevice[ nodeA ][ 'available' ],
5297 'role': idToDevice[ nodeA ][ 'role' ],
5298 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5299 'hw': idToDevice[ nodeA ][ 'hw' ],
5300 'sw': idToDevice[ nodeA ][ 'sw' ],
5301 'serial': idToDevice[ nodeA ][ 'serial' ],
5302 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005303 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005304 else:
5305 # Assert nodeB is not connected to any current links of nodeA
5306 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005307 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5308 'type': link[ 'type' ],
5309 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005310 return graphDict
5311 except ( TypeError, ValueError ):
5312 main.log.exception( self.name + ": Object not as expected" )
5313 return None
5314 except KeyError:
5315 main.log.exception( self.name + ": KeyError exception found" )
5316 return None
5317 except AssertionError:
5318 main.log.exception( self.name + ": AssertionError exception found" )
5319 return None
5320 except pexpect.EOF:
5321 main.log.error( self.name + ": EOF exception found" )
5322 main.log.error( self.name + ": " + self.handle.before )
5323 return None
5324 except Exception:
5325 main.log.exception( self.name + ": Uncaught exception!" )
5326 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005327
5328 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005329 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005330 Send command to check intent-perf summary
5331 Returns: dictionary for intent-perf summary
5332 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005333 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005334 cmd = "intent-perf -s"
5335 respDic = {}
5336 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005337 assert resp is not None, "Error in sendline"
5338 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005339 try:
5340 # Generate the dictionary to return
5341 for l in resp.split( "\n" ):
5342 # Delete any white space in line
5343 temp = re.sub( r'\s+', '', l )
5344 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005345 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005346
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005347 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005348 main.log.exception( self.name + ": Object not as expected" )
5349 return None
5350 except KeyError:
5351 main.log.exception( self.name + ": KeyError exception found" )
5352 return None
5353 except AssertionError:
5354 main.log.exception( self.name + ": AssertionError exception found" )
5355 return None
5356 except pexpect.EOF:
5357 main.log.error( self.name + ": EOF exception found" )
5358 main.log.error( self.name + ": " + self.handle.before )
5359 return None
5360 except Exception:
5361 main.log.exception( self.name + ": Uncaught exception!" )
5362 return None
5363 return respDic
5364
Chiyu Chengec63bde2016-11-17 18:11:36 -08005365 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005366 """
5367 Searches the latest ONOS log file for the given search term and
5368 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005369
chengchiyu08303a02016-09-08 17:40:26 -07005370 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005371 searchTerm:
5372 The string to grep from the ONOS log.
5373 startLine:
5374 The term that decides which line is the start to search the searchTerm in
5375 the karaf log. For now, startTerm only works in 'first' mode.
5376 logNum:
5377 In some extreme cases, one karaf log is not big enough to contain all the
5378 information.Because of this, search mutiply logs is necessary to capture
5379 the right result. logNum is the number of karaf logs that we need to search
5380 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005381 mode:
5382 all: return all the strings that contain the search term
5383 last: return the last string that contains the search term
5384 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005385 num: return the number of times that the searchTerm appears in the log
5386 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005387 """
5388 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005389 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005390 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005391 logPath = '/opt/onos/log/karaf.log.'
5392 logPaths = '/opt/onos/log/karaf.log'
5393 for i in range( 1, logNum ):
5394 logPaths = logPath + str( i ) + " " + logPaths
5395 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005396 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005397 # 100000000 is just a extreme large number to make sure this function can
5398 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005399 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005400 if mode == 'all':
5401 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005402 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005403 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005404 elif mode == 'first':
5405 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5406 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005407 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005408 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005409 return num
You Wang6d301d42017-04-21 10:49:33 -07005410 elif mode == 'total':
Jon Halld5a94fb2018-11-13 14:32:23 -08005411 totalLines = self.lineCount( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005412 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005413 else:
5414 main.log.error( self.name + " unsupported mode" )
5415 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005416 before = self.sendline( cmd )
5417 before = before.splitlines()
5418 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005419 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005420 return returnLines
5421 except AssertionError:
5422 main.log.error( self.name + " searchTerm is not string type" )
5423 return None
5424 except pexpect.EOF:
5425 main.log.error( self.name + ": EOF exception found" )
5426 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005427 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005428 except pexpect.TIMEOUT:
5429 main.log.error( self.name + ": TIMEOUT exception found" )
5430 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005431 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005432 except Exception:
5433 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005434 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005435
5436 def vplsShow( self, jsonFormat=True ):
5437 """
5438 Description: Returns result of onos:vpls show, which should list the
5439 configured VPLS networks and the assigned interfaces.
5440 Optional:
5441 * jsonFormat: enable json formatting of output
5442 Returns:
5443 The output of the command or None on error.
5444 """
5445 try:
5446 cmdStr = "vpls show"
5447 if jsonFormat:
5448 raise NotImplementedError
5449 cmdStr += " -j"
5450 handle = self.sendline( cmdStr )
5451 assert handle is not None, "Error in sendline"
5452 assert "Command not found:" not in handle, handle
5453 return handle
5454 except AssertionError:
5455 main.log.exception( "" )
5456 return None
5457 except TypeError:
5458 main.log.exception( self.name + ": Object not as expected" )
5459 return None
5460 except pexpect.EOF:
5461 main.log.error( self.name + ": EOF exception found" )
5462 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005463 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005464 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005465 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005466 return None
5467 except Exception:
5468 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005469 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005470
5471 def parseVplsShow( self ):
5472 """
5473 Parse the cli output of 'vpls show' into json output. This is required
5474 as there is currently no json output available.
5475 """
5476 try:
5477 output = []
5478 raw = self.vplsShow( jsonFormat=False )
5479 namePat = "VPLS name: (?P<name>\w+)"
5480 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5481 encapPat = "Encapsulation: (?P<encap>\w+)"
5482 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5483 mIter = re.finditer( pattern, raw )
5484 for match in mIter:
5485 item = {}
5486 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005487 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005488 if ifaces == [ "" ]:
5489 ifaces = []
5490 item[ 'interfaces' ] = ifaces
5491 encap = match.group( 'encap' )
5492 if encap != 'NONE':
5493 item[ 'encapsulation' ] = encap.lower()
5494 output.append( item )
5495 return output
5496 except Exception:
5497 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005498 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005499
5500 def vplsList( self, jsonFormat=True ):
5501 """
5502 Description: Returns result of onos:vpls list, which should list the
5503 configured VPLS networks.
5504 Optional:
5505 * jsonFormat: enable json formatting of output
5506 """
5507 try:
5508 cmdStr = "vpls list"
5509 if jsonFormat:
5510 raise NotImplementedError
5511 cmdStr += " -j"
5512 handle = self.sendline( cmdStr )
5513 assert handle is not None, "Error in sendline"
5514 assert "Command not found:" not in handle, handle
5515 return handle
5516 except AssertionError:
5517 main.log.exception( "" )
5518 return None
5519 except TypeError:
5520 main.log.exception( self.name + ": Object not as expected" )
5521 return None
5522 except pexpect.EOF:
5523 main.log.error( self.name + ": EOF exception found" )
5524 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005525 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005526 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005527 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005528 return None
5529 except Exception:
5530 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005531 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005532
5533 def vplsCreate( self, network ):
5534 """
5535 CLI command to create a new VPLS network.
5536 Required arguments:
5537 network - String name of the network to create.
5538 returns:
5539 main.TRUE on success and main.FALSE on failure
5540 """
5541 try:
5542 network = str( network )
5543 cmdStr = "vpls create "
5544 cmdStr += network
5545 output = self.sendline( cmdStr )
5546 assert output is not None, "Error in sendline"
5547 assert "Command not found:" not in output, output
5548 assert "Error executing command" not in output, output
5549 assert "VPLS already exists:" not in output, output
5550 return main.TRUE
5551 except AssertionError:
5552 main.log.exception( "" )
5553 return main.FALSE
5554 except TypeError:
5555 main.log.exception( self.name + ": Object not as expected" )
5556 return main.FALSE
5557 except pexpect.EOF:
5558 main.log.error( self.name + ": EOF exception found" )
5559 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005560 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005561 except Exception:
5562 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005563 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005564
5565 def vplsDelete( self, network ):
5566 """
5567 CLI command to delete a VPLS network.
5568 Required arguments:
5569 network - Name of the network to delete.
5570 returns:
5571 main.TRUE on success and main.FALSE on failure
5572 """
5573 try:
5574 network = str( network )
5575 cmdStr = "vpls delete "
5576 cmdStr += network
5577 output = self.sendline( cmdStr )
5578 assert output is not None, "Error in sendline"
5579 assert "Command not found:" not in output, output
5580 assert "Error executing command" not in output, output
5581 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005582 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005583 return main.TRUE
5584 except AssertionError:
5585 main.log.exception( "" )
5586 return main.FALSE
5587 except TypeError:
5588 main.log.exception( self.name + ": Object not as expected" )
5589 return main.FALSE
5590 except pexpect.EOF:
5591 main.log.error( self.name + ": EOF exception found" )
5592 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005593 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005594 except Exception:
5595 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005596 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005597
5598 def vplsAddIface( self, network, iface ):
5599 """
5600 CLI command to add an interface to a VPLS network.
5601 Required arguments:
5602 network - Name of the network to add the interface to.
5603 iface - The ONOS name for an interface.
5604 returns:
5605 main.TRUE on success and main.FALSE on failure
5606 """
5607 try:
5608 network = str( network )
5609 iface = str( iface )
5610 cmdStr = "vpls add-if "
5611 cmdStr += network + " " + iface
5612 output = self.sendline( cmdStr )
5613 assert output is not None, "Error in sendline"
5614 assert "Command not found:" not in output, output
5615 assert "Error executing command" not in output, output
5616 assert "already associated to network" not in output, output
5617 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005618 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005619 return main.TRUE
5620 except AssertionError:
5621 main.log.exception( "" )
5622 return main.FALSE
5623 except TypeError:
5624 main.log.exception( self.name + ": Object not as expected" )
5625 return main.FALSE
5626 except pexpect.EOF:
5627 main.log.error( self.name + ": EOF exception found" )
5628 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005629 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005630 except Exception:
5631 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005632 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005633
5634 def vplsRemIface( self, network, iface ):
5635 """
5636 CLI command to remove an interface from a VPLS network.
5637 Required arguments:
5638 network - Name of the network to remove the interface from.
5639 iface - Name of the interface to remove.
5640 returns:
5641 main.TRUE on success and main.FALSE on failure
5642 """
5643 try:
5644 iface = str( iface )
5645 cmdStr = "vpls rem-if "
5646 cmdStr += network + " " + iface
5647 output = self.sendline( cmdStr )
5648 assert output is not None, "Error in sendline"
5649 assert "Command not found:" not in output, output
5650 assert "Error executing command" not in output, output
5651 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005652 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005653 return main.TRUE
5654 except AssertionError:
5655 main.log.exception( "" )
5656 return main.FALSE
5657 except TypeError:
5658 main.log.exception( self.name + ": Object not as expected" )
5659 return main.FALSE
5660 except pexpect.EOF:
5661 main.log.error( self.name + ": EOF exception found" )
5662 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005663 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005664 except Exception:
5665 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005666 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005667
5668 def vplsClean( self ):
5669 """
5670 Description: Clears the VPLS app configuration.
5671 Returns: main.TRUE on success and main.FALSE on failure
5672 """
5673 try:
5674 cmdStr = "vpls clean"
5675 handle = self.sendline( cmdStr )
5676 assert handle is not None, "Error in sendline"
5677 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005678 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005679 return handle
5680 except AssertionError:
5681 main.log.exception( "" )
5682 return main.FALSE
5683 except TypeError:
5684 main.log.exception( self.name + ": Object not as expected" )
5685 return main.FALSE
5686 except pexpect.EOF:
5687 main.log.error( self.name + ": EOF exception found" )
5688 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005689 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005690 except Exception:
5691 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005692 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005693
5694 def vplsSetEncap( self, network, encapType ):
5695 """
5696 CLI command to add an interface to a VPLS network.
5697 Required arguments:
5698 network - Name of the network to create.
5699 encapType - Type of encapsulation.
5700 returns:
5701 main.TRUE on success and main.FALSE on failure
5702 """
5703 try:
5704 network = str( network )
5705 encapType = str( encapType ).upper()
5706 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5707 cmdStr = "vpls set-encap "
5708 cmdStr += network + " " + encapType
5709 output = self.sendline( cmdStr )
5710 assert output is not None, "Error in sendline"
5711 assert "Command not found:" not in output, output
5712 assert "Error executing command" not in output, output
5713 assert "already associated to network" not in output, output
5714 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005715 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005716 return main.TRUE
5717 except AssertionError:
5718 main.log.exception( "" )
5719 return main.FALSE
5720 except TypeError:
5721 main.log.exception( self.name + ": Object not as expected" )
5722 return main.FALSE
5723 except pexpect.EOF:
5724 main.log.error( self.name + ": EOF exception found" )
5725 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005726 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005727 except Exception:
5728 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005729 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005730
5731 def interfaces( self, jsonFormat=True ):
5732 """
5733 Description: Returns result of interfaces command.
5734 Optional:
5735 * jsonFormat: enable json formatting of output
5736 Returns:
5737 The output of the command or None on error.
5738 """
5739 try:
5740 cmdStr = "interfaces"
5741 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005742 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005743 cmdStr += " -j"
5744 handle = self.sendline( cmdStr )
5745 assert handle is not None, "Error in sendline"
5746 assert "Command not found:" not in handle, handle
5747 return handle
5748 except AssertionError:
5749 main.log.exception( "" )
5750 return None
5751 except TypeError:
5752 main.log.exception( self.name + ": Object not as expected" )
5753 return None
5754 except pexpect.EOF:
5755 main.log.error( self.name + ": EOF exception found" )
5756 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005757 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005758 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005759 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005760 return None
5761 except Exception:
5762 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005763 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005764
5765 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005766 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005767 Get the timestamp of searchTerm from karaf log.
5768
5769 Arguments:
5770 splitTerm_before and splitTerm_after:
5771
5772 The terms that split the string that contains the timeStamp of
5773 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5774 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5775 and the splitTerm_after is "x"
5776
5777 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005778 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005779 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005780 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005781 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005782 return main.ERROR
5783 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005784 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005785 main.log.warn( "Captured timestamp string is empty" )
5786 return main.ERROR
5787 lines = lines[ 0 ]
5788 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005789 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005790 # get the target value
5791 line = lines.split( splitTerm_before )
5792 key = line[ 1 ].split( splitTerm_after )
5793 return int( key[ 0 ] )
5794 except IndexError:
5795 main.log.warn( "Index Error!" )
5796 return main.ERROR
5797 except AssertionError:
5798 main.log.warn( "Search Term Not Found " )
5799 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005800
5801 def workQueueAdd( self, queueName, value ):
5802 """
5803 CLI command to add a string to the specified Work Queue.
5804 This function uses the distributed primitives test app, which
5805 gives some cli access to distributed primitives for testing
5806 purposes only.
5807
5808 Required arguments:
5809 queueName - The name of the queue to add to
5810 value - The value to add to the queue
5811 returns:
5812 main.TRUE on success, main.FALSE on failure and
5813 main.ERROR on error.
5814 """
5815 try:
5816 queueName = str( queueName )
5817 value = str( value )
5818 prefix = "work-queue-test"
5819 operation = "add"
5820 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5821 output = self.distPrimitivesSend( cmdStr )
5822 if "Invalid operation name" in output:
5823 main.log.warn( output )
5824 return main.ERROR
5825 elif "Done" in output:
5826 return main.TRUE
5827 except TypeError:
5828 main.log.exception( self.name + ": Object not as expected" )
5829 return main.ERROR
5830 except Exception:
5831 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005832 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005833
5834 def workQueueAddMultiple( self, queueName, value1, value2 ):
5835 """
5836 CLI command to add two strings to the specified Work Queue.
5837 This function uses the distributed primitives test app, which
5838 gives some cli access to distributed primitives for testing
5839 purposes only.
5840
5841 Required arguments:
5842 queueName - The name of the queue to add to
5843 value1 - The first value to add to the queue
5844 value2 - The second value to add to the queue
5845 returns:
5846 main.TRUE on success, main.FALSE on failure and
5847 main.ERROR on error.
5848 """
5849 try:
5850 queueName = str( queueName )
5851 value1 = str( value1 )
5852 value2 = str( value2 )
5853 prefix = "work-queue-test"
5854 operation = "addMultiple"
5855 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5856 output = self.distPrimitivesSend( cmdStr )
5857 if "Invalid operation name" in output:
5858 main.log.warn( output )
5859 return main.ERROR
5860 elif "Done" in output:
5861 return main.TRUE
5862 except TypeError:
5863 main.log.exception( self.name + ": Object not as expected" )
5864 return main.ERROR
5865 except Exception:
5866 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005867 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005868
5869 def workQueueTakeAndComplete( self, queueName, number=1 ):
5870 """
5871 CLI command to take a value from the specified Work Queue and compelte it.
5872 This function uses the distributed primitives test app, which
5873 gives some cli access to distributed primitives for testing
5874 purposes only.
5875
5876 Required arguments:
5877 queueName - The name of the queue to add to
5878 number - The number of items to take and complete
5879 returns:
5880 main.TRUE on success, main.FALSE on failure and
5881 main.ERROR on error.
5882 """
5883 try:
5884 queueName = str( queueName )
5885 number = str( int( number ) )
5886 prefix = "work-queue-test"
5887 operation = "takeAndComplete"
5888 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5889 output = self.distPrimitivesSend( cmdStr )
5890 if "Invalid operation name" in output:
5891 main.log.warn( output )
5892 return main.ERROR
5893 elif "Done" in output:
5894 return main.TRUE
5895 except TypeError:
5896 main.log.exception( self.name + ": Object not as expected" )
5897 return main.ERROR
5898 except Exception:
5899 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005900 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005901
5902 def workQueueDestroy( self, queueName ):
5903 """
5904 CLI command to destroy the specified Work Queue.
5905 This function uses the distributed primitives test app, which
5906 gives some cli access to distributed primitives for testing
5907 purposes only.
5908
5909 Required arguments:
5910 queueName - The name of the queue to add to
5911 returns:
5912 main.TRUE on success, main.FALSE on failure and
5913 main.ERROR on error.
5914 """
5915 try:
5916 queueName = str( queueName )
5917 prefix = "work-queue-test"
5918 operation = "destroy"
5919 cmdStr = " ".join( [ prefix, queueName, operation ] )
5920 output = self.distPrimitivesSend( cmdStr )
5921 if "Invalid operation name" in output:
5922 main.log.warn( output )
5923 return main.ERROR
5924 return main.TRUE
5925 except TypeError:
5926 main.log.exception( self.name + ": Object not as expected" )
5927 return main.ERROR
5928 except Exception:
5929 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005930 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005931
5932 def workQueueTotalPending( self, queueName ):
5933 """
5934 CLI command to get the Total Pending items of the specified Work Queue.
5935 This function uses the distributed primitives test app, which
5936 gives some cli access to distributed primitives for testing
5937 purposes only.
5938
5939 Required arguments:
5940 queueName - The name of the queue to add to
5941 returns:
5942 The number of Pending items in the specified work queue or
5943 None on error
5944 """
5945 try:
5946 queueName = str( queueName )
5947 prefix = "work-queue-test"
5948 operation = "totalPending"
5949 cmdStr = " ".join( [ prefix, queueName, operation ] )
5950 output = self.distPrimitivesSend( cmdStr )
5951 pattern = r'\d+'
5952 if "Invalid operation name" in output:
5953 main.log.warn( output )
5954 return None
5955 else:
5956 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005957 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005958 except ( AttributeError, TypeError ):
5959 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5960 return None
5961 except Exception:
5962 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005963 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005964
5965 def workQueueTotalCompleted( self, queueName ):
5966 """
5967 CLI command to get the Total Completed items of the specified Work Queue.
5968 This function uses the distributed primitives test app, which
5969 gives some cli access to distributed primitives for testing
5970 purposes only.
5971
5972 Required arguments:
5973 queueName - The name of the queue to add to
5974 returns:
5975 The number of complete items in the specified work queue or
5976 None on error
5977 """
5978 try:
5979 queueName = str( queueName )
5980 prefix = "work-queue-test"
5981 operation = "totalCompleted"
5982 cmdStr = " ".join( [ prefix, queueName, operation ] )
5983 output = self.distPrimitivesSend( cmdStr )
5984 pattern = r'\d+'
5985 if "Invalid operation name" in output:
5986 main.log.warn( output )
5987 return None
5988 else:
5989 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005990 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005991 except ( AttributeError, TypeError ):
5992 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5993 return None
5994 except Exception:
5995 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005996 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005997
5998 def workQueueTotalInProgress( self, queueName ):
5999 """
6000 CLI command to get the Total In Progress items of the specified Work Queue.
6001 This function uses the distributed primitives test app, which
6002 gives some cli access to distributed primitives for testing
6003 purposes only.
6004
6005 Required arguments:
6006 queueName - The name of the queue to add to
6007 returns:
6008 The number of In Progress items in the specified work queue or
6009 None on error
6010 """
6011 try:
6012 queueName = str( queueName )
6013 prefix = "work-queue-test"
6014 operation = "totalInProgress"
6015 cmdStr = " ".join( [ prefix, queueName, operation ] )
6016 output = self.distPrimitivesSend( cmdStr )
6017 pattern = r'\d+'
6018 if "Invalid operation name" in output:
6019 main.log.warn( output )
6020 return None
6021 else:
6022 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07006023 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07006024 except ( AttributeError, TypeError ):
6025 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
6026 return None
6027 except Exception:
6028 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07006029 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00006030
6031 def events( self, args='-a' ):
6032 """
6033 Description: Returns events -a command output
6034 Optional:
6035 add other arguments
6036 """
6037 try:
6038 cmdStr = "events"
6039 if args:
6040 cmdStr += " " + args
6041 handle = self.sendline( cmdStr )
6042 assert handle is not None, "Error in sendline"
6043 assert "Command not found:" not in handle, handle
6044 return handle
6045 except AssertionError:
6046 main.log.exception( "" )
6047 return None
6048 except TypeError:
6049 main.log.exception( self.name + ": Object not as expected" )
6050 return None
6051 except pexpect.EOF:
6052 main.log.error( self.name + ": EOF exception found" )
6053 main.log.error( self.name + ": " + self.handle.before )
6054 main.cleanAndExit()
6055 except Exception:
6056 main.log.exception( self.name + ": Uncaught exception!" )
6057 main.cleanAndExit()
6058
6059 def getMaster( self, deviceID ):
6060 """
6061 Description: Obtains current master using "roles" command for a specific deviceID
6062 """
6063 try:
6064 return str( self.getRole( deviceID )[ 'master' ] )
6065 except AssertionError:
6066 main.log.exception( "" )
6067 return None
6068 except TypeError:
6069 main.log.exception( self.name + ": Object not as expected" )
6070 return None
6071 except pexpect.EOF:
6072 main.log.error( self.name + ": EOF exception found" )
6073 main.log.error( self.name + ": " + self.handle.before )
6074 main.cleanAndExit()
6075 except Exception:
6076 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006077 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006078
6079 def issu( self ):
6080 """
6081 Short summary of In-Service Software Upgrade status
6082
6083 Returns the output of the cli command or None on Error
6084 """
6085 try:
6086 cmdStr = "issu"
6087 handle = self.sendline( cmdStr )
6088 assert handle is not None, "Error in sendline"
6089 assert "Command not found:" not in handle, handle
6090 assert "Unsupported command:" not in handle, handle
6091 return handle
6092 except AssertionError:
6093 main.log.exception( "" )
6094 return None
6095 except TypeError:
6096 main.log.exception( self.name + ": Object not as expected" )
6097 return None
6098 except pexpect.EOF:
6099 main.log.error( self.name + ": EOF exception found" )
6100 main.log.error( self.name + ": " + self.handle.before )
6101 main.cleanAndExit()
6102 except Exception:
6103 main.log.exception( self.name + ": Uncaught exception!" )
6104 main.cleanAndExit()
6105
6106 def issuInit( self ):
6107 """
6108 Initiates an In-Service Software Upgrade
6109
6110 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6111 """
6112 try:
6113 cmdStr = "issu init"
6114 handle = self.sendline( cmdStr )
6115 assert handle is not None, "Error in sendline"
6116 assert "Command not found:" not in handle, handle
6117 assert "Unsupported command:" not in handle, handle
6118 if "Initialized" in handle:
6119 return main.TRUE
6120 else:
6121 return main.FALSE
6122 except AssertionError:
6123 main.log.exception( "" )
6124 return main.ERROR
6125 except TypeError:
6126 main.log.exception( self.name + ": Object not as expected" )
6127 return main.ERROR
6128 except pexpect.EOF:
6129 main.log.error( self.name + ": EOF exception found" )
6130 main.log.error( self.name + ": " + self.handle.before )
6131 main.cleanAndExit()
6132 except Exception:
6133 main.log.exception( self.name + ": Uncaught exception!" )
6134 main.cleanAndExit()
6135
6136 def issuUpgrade( self ):
6137 """
6138 Transitions stores to upgraded nodes
6139
6140 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6141 """
6142 try:
6143 cmdStr = "issu upgrade"
6144 handle = self.sendline( cmdStr )
6145 assert handle is not None, "Error in sendline"
6146 assert "Command not found:" not in handle, handle
6147 assert "Unsupported command:" not in handle, handle
6148 if "Upgraded" in handle:
6149 return main.TRUE
6150 else:
6151 return main.FALSE
6152 except AssertionError:
6153 main.log.exception( "" )
6154 return main.ERROR
6155 except TypeError:
6156 main.log.exception( self.name + ": Object not as expected" )
6157 return main.ERROR
6158 except pexpect.EOF:
6159 main.log.error( self.name + ": EOF exception found" )
6160 main.log.error( self.name + ": " + self.handle.before )
6161 main.cleanAndExit()
6162 except Exception:
6163 main.log.exception( self.name + ": Uncaught exception!" )
6164 main.cleanAndExit()
6165
6166 def issuCommit( self ):
6167 """
6168 Finalizes an In-Service Software Upgrade
6169
6170 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6171 """
6172 try:
6173 cmdStr = "issu commit"
6174 handle = self.sendline( cmdStr )
6175 assert handle is not None, "Error in sendline"
6176 assert "Command not found:" not in handle, handle
6177 assert "Unsupported command:" not in handle, handle
6178 # TODO: Check the version returned by this command
6179 if "Committed version" in handle:
6180 return main.TRUE
6181 else:
6182 return main.FALSE
6183 except AssertionError:
6184 main.log.exception( "" )
6185 return main.ERROR
6186 except TypeError:
6187 main.log.exception( self.name + ": Object not as expected" )
6188 return main.ERROR
6189 except pexpect.EOF:
6190 main.log.error( self.name + ": EOF exception found" )
6191 main.log.error( self.name + ": " + self.handle.before )
6192 main.cleanAndExit()
6193 except Exception:
6194 main.log.exception( self.name + ": Uncaught exception!" )
6195 main.cleanAndExit()
6196
6197 def issuRollback( self ):
6198 """
6199 Rolls back an In-Service Software Upgrade
6200
6201 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6202 """
6203 try:
6204 cmdStr = "issu rollback"
6205 handle = self.sendline( cmdStr )
6206 assert handle is not None, "Error in sendline"
6207 assert "Command not found:" not in handle, handle
6208 assert "Unsupported command:" not in handle, handle
6209 # TODO: Check the version returned by this command
6210 if "Rolled back to version" in handle:
6211 return main.TRUE
6212 else:
6213 return main.FALSE
6214 except AssertionError:
6215 main.log.exception( "" )
6216 return main.ERROR
6217 except TypeError:
6218 main.log.exception( self.name + ": Object not as expected" )
6219 return main.ERROR
6220 except pexpect.EOF:
6221 main.log.error( self.name + ": EOF exception found" )
6222 main.log.error( self.name + ": " + self.handle.before )
6223 main.cleanAndExit()
6224 except Exception:
6225 main.log.exception( self.name + ": Uncaught exception!" )
6226 main.cleanAndExit()
6227
6228 def issuReset( self ):
6229 """
6230 Resets the In-Service Software Upgrade status after a rollback
6231
6232 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6233 """
6234 try:
6235 cmdStr = "issu reset"
6236 handle = self.sendline( cmdStr )
6237 assert handle is not None, "Error in sendline"
6238 assert "Command not found:" not in handle, handle
6239 assert "Unsupported command:" not in handle, handle
6240 # TODO: Check the version returned by this command
6241 if "Reset version" in handle:
6242 return main.TRUE
6243 else:
6244 return main.FALSE
6245 except AssertionError:
6246 main.log.exception( "" )
6247 return main.ERROR
6248 except TypeError:
6249 main.log.exception( self.name + ": Object not as expected" )
6250 return main.ERROR
6251 except pexpect.EOF:
6252 main.log.error( self.name + ": EOF exception found" )
6253 main.log.error( self.name + ": " + self.handle.before )
6254 main.cleanAndExit()
6255 except Exception:
6256 main.log.exception( self.name + ": Uncaught exception!" )
6257 main.cleanAndExit()
6258
6259 def issuStatus( self ):
6260 """
6261 Status of an In-Service Software Upgrade
6262
6263 Returns the output of the cli command or None on Error
6264 """
6265 try:
6266 cmdStr = "issu status"
6267 handle = self.sendline( cmdStr )
6268 assert handle is not None, "Error in sendline"
6269 assert "Command not found:" not in handle, handle
6270 assert "Unsupported command:" not in handle, handle
6271 return handle
6272 except AssertionError:
6273 main.log.exception( "" )
6274 return None
6275 except TypeError:
6276 main.log.exception( self.name + ": Object not as expected" )
6277 return None
6278 except pexpect.EOF:
6279 main.log.error( self.name + ": EOF exception found" )
6280 main.log.error( self.name + ": " + self.handle.before )
6281 main.cleanAndExit()
6282 except Exception:
6283 main.log.exception( self.name + ": Uncaught exception!" )
6284 main.cleanAndExit()
6285
6286 def issuVersion( self ):
6287 """
6288 Get the version of an In-Service Software Upgrade
6289
6290 Returns the output of the cli command or None on Error
6291 """
6292 try:
6293 cmdStr = "issu version"
6294 handle = self.sendline( cmdStr )
6295 assert handle is not None, "Error in sendline"
6296 assert "Command not found:" not in handle, handle
6297 assert "Unsupported command:" not in handle, handle
6298 return handle
6299 except AssertionError:
6300 main.log.exception( "" )
6301 return None
6302 except TypeError:
6303 main.log.exception( self.name + ": Object not as expected" )
6304 return None
6305 except pexpect.EOF:
6306 main.log.error( self.name + ": EOF exception found" )
6307 main.log.error( self.name + ": " + self.handle.before )
6308 main.cleanAndExit()
6309 except Exception:
6310 main.log.exception( self.name + ": Uncaught exception!" )
6311 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006312
6313 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6314 """
6315 Create a multicast route by calling 'mcast-join' command
6316 sIP: source IP of the multicast route
6317 groupIP: group IP of the multicast route
6318 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6319 dPorts: a list of destination ports of the multicast route
6320 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6321 """
6322 try:
6323 cmdStr = "mcast-join"
6324 cmdStr += " " + str( sIP )
6325 cmdStr += " " + str( groupIP )
6326 cmdStr += " " + str( sPort )
6327 assert isinstance( dPorts, list )
6328 for dPort in dPorts:
6329 cmdStr += " " + str( dPort )
6330 handle = self.sendline( cmdStr )
6331 assert handle is not None, "Error in sendline"
6332 assert "Command not found:" not in handle, handle
6333 assert "Unsupported command:" not in handle, handle
6334 assert "Error executing command" not in handle, handle
6335 if "Added the mcast route" in handle:
6336 return main.TRUE
6337 else:
6338 return main.FALSE
6339 except AssertionError:
6340 main.log.exception( "" )
6341 return None
6342 except TypeError:
6343 main.log.exception( self.name + ": Object not as expected" )
6344 return None
6345 except pexpect.EOF:
6346 main.log.error( self.name + ": EOF exception found" )
6347 main.log.error( self.name + ": " + self.handle.before )
6348 main.cleanAndExit()
6349 except Exception:
6350 main.log.exception( self.name + ": Uncaught exception!" )
6351 main.cleanAndExit()
6352
6353 def mcastDelete( self, sIP, groupIP, dPorts ):
6354 """
6355 Delete a multicast route by calling 'mcast-delete' command
6356 sIP: source IP of the multicast route
6357 groupIP: group IP of the multicast route
6358 dPorts: a list of destination ports of the multicast route
6359 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6360 """
6361 try:
6362 cmdStr = "mcast-delete"
6363 cmdStr += " " + str( sIP )
6364 cmdStr += " " + str( groupIP )
6365 assert isinstance( dPorts, list )
6366 for dPort in dPorts:
6367 cmdStr += " " + str( dPort )
6368 handle = self.sendline( cmdStr )
6369 assert handle is not None, "Error in sendline"
6370 assert "Command not found:" not in handle, handle
6371 assert "Unsupported command:" not in handle, handle
6372 assert "Error executing command" not in handle, handle
6373 if "Updated the mcast route" in handle:
6374 return main.TRUE
6375 else:
6376 return main.FALSE
6377 except AssertionError:
6378 main.log.exception( "" )
6379 return None
6380 except TypeError:
6381 main.log.exception( self.name + ": Object not as expected" )
6382 return None
6383 except pexpect.EOF:
6384 main.log.error( self.name + ": EOF exception found" )
6385 main.log.error( self.name + ": " + self.handle.before )
6386 main.cleanAndExit()
6387 except Exception:
6388 main.log.exception( self.name + ": Uncaught exception!" )
6389 main.cleanAndExit()
6390
6391 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6392 """
6393 Create a multicast route by calling 'mcast-host-join' command
6394 sAddr: we can provide * for ASM or a specific address for SSM
6395 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006396 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006397 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6398 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6399 """
6400 try:
6401 cmdStr = "mcast-host-join"
6402 cmdStr += " -sAddr " + str( sAddr )
6403 cmdStr += " -gAddr " + str( gAddr )
6404 assert isinstance( srcs, list )
6405 for src in srcs:
6406 cmdStr += " -srcs " + str( src )
6407 assert isinstance( sinks, list )
6408 for sink in sinks:
6409 cmdStr += " -sinks " + str( sink )
6410 handle = self.sendline( cmdStr )
6411 assert handle is not None, "Error in sendline"
6412 assert "Command not found:" not in handle, handle
6413 assert "Unsupported command:" not in handle, handle
6414 assert "Error executing command" not in handle, handle
6415 if "Added the mcast route" in handle:
6416 return main.TRUE
6417 else:
6418 return main.FALSE
6419 except AssertionError:
6420 main.log.exception( "" )
6421 return None
6422 except TypeError:
6423 main.log.exception( self.name + ": Object not as expected" )
6424 return None
6425 except pexpect.EOF:
6426 main.log.error( self.name + ": EOF exception found" )
6427 main.log.error( self.name + ": " + self.handle.before )
6428 main.cleanAndExit()
6429 except Exception:
6430 main.log.exception( self.name + ": Uncaught exception!" )
6431 main.cleanAndExit()
6432
6433 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6434 """
6435 Delete multicast sink(s) by calling 'mcast-host-delete' command
6436 sAddr: we can provide * for ASM or a specific address for SSM
6437 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006438 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006439 will delete the route if not specified
6440 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6441 """
6442 try:
6443 cmdStr = "mcast-host-delete"
6444 cmdStr += " -sAddr " + str( sAddr )
6445 cmdStr += " -gAddr " + str( gAddr )
6446 if host:
6447 cmdStr += " -h " + str( host )
6448 handle = self.sendline( cmdStr )
6449 assert handle is not None, "Error in sendline"
6450 assert "Command not found:" not in handle, handle
6451 assert "Unsupported command:" not in handle, handle
6452 assert "Error executing command" not in handle, handle
6453 if "Updated the mcast route" in handle:
6454 return main.TRUE
6455 elif "Deleted the mcast route" in handle:
6456 return main.TRUE
6457 else:
6458 return main.FALSE
6459 except AssertionError:
6460 main.log.exception( "" )
6461 return None
6462 except TypeError:
6463 main.log.exception( self.name + ": Object not as expected" )
6464 return None
6465 except pexpect.EOF:
6466 main.log.error( self.name + ": EOF exception found" )
6467 main.log.error( self.name + ": " + self.handle.before )
6468 main.cleanAndExit()
6469 except Exception:
6470 main.log.exception( self.name + ": Uncaught exception!" )
6471 main.cleanAndExit()
6472
You Wang547893e2018-05-08 13:34:59 -07006473 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6474 """
6475 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6476 sAddr: we can provide * for ASM or a specific address for SSM
6477 gAddr: specifies multicast group address
6478 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6479 will delete the route if not specified
6480 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6481 """
6482 try:
6483 cmdStr = "mcast-sink-delete"
6484 cmdStr += " -sAddr " + str( sAddr )
6485 cmdStr += " -gAddr " + str( gAddr )
6486 if sink:
6487 cmdStr += " -s " + str( sink )
6488 handle = self.sendline( cmdStr )
6489 assert handle is not None, "Error in sendline"
6490 assert "Command not found:" not in handle, handle
6491 assert "Unsupported command:" not in handle, handle
6492 assert "Error executing command" not in handle, handle
6493 if "Updated the mcast route" in handle:
6494 return main.TRUE
6495 elif "Deleted the mcast route" in handle:
6496 return main.TRUE
6497 else:
6498 return main.FALSE
6499 except AssertionError:
6500 main.log.exception( "" )
6501 return None
6502 except TypeError:
6503 main.log.exception( self.name + ": Object not as expected" )
6504 return None
6505 except pexpect.EOF:
6506 main.log.error( self.name + ": EOF exception found" )
6507 main.log.error( self.name + ": " + self.handle.before )
6508 main.cleanAndExit()
6509 except Exception:
6510 main.log.exception( self.name + ": Uncaught exception!" )
6511 main.cleanAndExit()
6512
You Wange24d6272018-03-27 21:18:50 -07006513 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6514 """
6515 Delete multicast src(s) by calling 'mcast-source-delete' command
6516 sAddr: we can provide * for ASM or a specific address for SSM
6517 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006518 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 -07006519 will delete the route if not specified
6520 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6521 """
6522 try:
6523 cmdStr = "mcast-source-delete"
6524 cmdStr += " -sAddr " + str( sAddr )
6525 cmdStr += " -gAddr " + str( gAddr )
6526 if srcs:
6527 assert isinstance( srcs, list )
6528 for src in srcs:
6529 cmdStr += " -src " + str( src )
6530 handle = self.sendline( cmdStr )
6531 assert handle is not None, "Error in sendline"
6532 assert "Command not found:" not in handle, handle
6533 assert "Unsupported command:" not in handle, handle
6534 assert "Error executing command" not in handle, handle
6535 if "Updated the mcast route" in handle:
6536 return main.TRUE
6537 elif "Deleted the mcast route" in handle:
6538 return main.TRUE
6539 else:
6540 return main.FALSE
6541 except AssertionError:
6542 main.log.exception( "" )
6543 return None
6544 except TypeError:
6545 main.log.exception( self.name + ": Object not as expected" )
6546 return None
6547 except pexpect.EOF:
6548 main.log.error( self.name + ": EOF exception found" )
6549 main.log.error( self.name + ": " + self.handle.before )
6550 main.cleanAndExit()
6551 except Exception:
6552 main.log.exception( self.name + ": Uncaught exception!" )
6553 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006554
6555 def netcfg( self, jsonFormat=True, args="" ):
6556 """
6557 Run netcfg cli command with given args
6558 """
6559 try:
6560 cmdStr = "netcfg"
6561 if jsonFormat:
6562 cmdStr = cmdStr + " -j"
6563 if args:
6564 cmdStr = cmdStr + " " + str( args )
6565 handle = self.sendline( cmdStr )
6566 assert handle is not None, "Error in sendline"
6567 assert "Command not found:" not in handle, handle
6568 assert "Unsupported command:" not in handle, handle
6569 assert "Error executing command" not in handle, handle
6570 return handle
6571 except AssertionError:
6572 main.log.exception( "" )
6573 return None
6574 except TypeError:
6575 main.log.exception( self.name + ": Object not as expected" )
6576 return None
6577 except pexpect.EOF:
6578 main.log.error( self.name + ": EOF exception found" )
6579 main.log.error( self.name + ": " + self.handle.before )
6580 main.cleanAndExit()
6581 except Exception:
6582 main.log.exception( self.name + ": Uncaught exception!" )
6583 main.cleanAndExit()
6584
You Wang0fa76e72018-05-18 11:33:25 -07006585 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006586 """
You Wang54b1d672018-06-11 16:44:13 -07006587 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006588 Options:
6589 sAddr: IP address of the source host
6590 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006591 ipv6: True if hosts are IPv6
6592 verbose: return verbose t3 output if True
6593 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006594 """
6595 try:
6596 # Collect information of both hosts from onos
6597 hosts = self.hosts()
6598 hosts = json.loads( hosts )
6599 sHost = None
6600 dHost = None
6601 for host in hosts:
6602 if sAddr in host[ "ipAddresses" ]:
6603 sHost = host
6604 elif dAddr in host[ "ipAddresses" ]:
6605 dHost = host
6606 if sHost and dHost:
6607 break
6608 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006609 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006610 if simple:
6611 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006612 cmdStr = "t3-troubleshoot-simple"
6613 if verbose:
6614 cmdStr += " -vv"
6615 if ipv6:
6616 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006617 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006618 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006619 else:
You Wang54b1d672018-06-11 16:44:13 -07006620 for location in sHost[ "locations" ]:
6621 cmdStr = "t3-troubleshoot"
6622 if verbose:
6623 cmdStr += " -vv"
6624 if ipv6:
6625 cmdStr += " -et ipv6"
6626 cmdStr += " -s " + str( sAddr )
6627 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6628 cmdStr += " -sm " + str( sHost[ "mac" ] )
6629 if sHost[ "vlan" ] != "None":
6630 cmdStr += " -vid " + sHost[ "vlan" ]
6631 cmdStr += " -d " + str( dAddr )
6632 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6633 netcfg = json.loads( netcfg )
6634 assert netcfg, "Failed to get netcfg"
6635 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6636 cmdList.append( cmdStr )
6637 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006638 except AssertionError:
6639 main.log.exception( "" )
6640 return None
6641 except ( KeyError, TypeError ):
6642 main.log.exception( self.name + ": Object not as expected" )
6643 return None
6644 except Exception:
6645 main.log.exception( self.name + ": Uncaught exception!" )
6646 main.cleanAndExit()
6647
6648 def t3( self, sAddr, dAddr, ipv6=False ):
6649 """
You Wang54b1d672018-06-11 16:44:13 -07006650 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006651 Options:
6652 sAddr: IP address of the source host
6653 dAddr: IP address of the destination host
6654 """
6655 try:
You Wang54b1d672018-06-11 16:44:13 -07006656 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6657 assert cmdList is not None, "composeT3Command returned None"
6658 t3Output = ""
6659 for cmdStr in cmdList:
6660 handle = self.sendline( cmdStr )
6661 assert handle is not None, "Error in sendline"
6662 assert "Command not found:" not in handle, handle
6663 assert "Unsupported command:" not in handle, handle
6664 assert "Error executing command" not in handle, handle
6665 assert "Tracing packet" in handle
6666 t3Output += handle
6667 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006668 except AssertionError:
6669 main.log.exception( "" )
6670 return None
6671 except pexpect.EOF:
6672 main.log.error( self.name + ": EOF exception found" )
6673 main.log.error( self.name + ": " + self.handle.before )
6674 main.cleanAndExit()
6675 except Exception:
6676 main.log.exception( self.name + ": Uncaught exception!" )
6677 main.cleanAndExit()