blob: dd60fb4555f2d197c7a77167ac014d7194dcc3bd [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
You Wangdb8cd0a2016-05-26 15:19:45 -070061 self.graph = Graph()
Devin Limdc78e202017-06-09 18:30:07 -070062 super( OnosCliDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080063
Jeremy Ronquillo82705492017-10-18 14:19:55 -070064 def checkOptions( self, var, defaultVar ):
Devin Limdc78e202017-06-09 18:30:07 -070065 if var is None or var == "":
66 return defaultVar
67 return var
Jeremy Ronquillo82705492017-10-18 14:19:55 -070068
kelvin8ec71442015-01-15 16:57:00 -080069 def connect( self, **connectargs ):
70 """
andrewonlab95ce8322014-10-13 14:12:04 -040071 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080072 """
andrewonlab95ce8322014-10-13 14:12:04 -040073 try:
74 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080075 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070076 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040077 for key in self.options:
78 if key == "home":
Devin Limdc78e202017-06-09 18:30:07 -070079 self.home = self.options[ key ]
80 elif key == "karaf_username":
81 self.karafUser = self.options[ key ]
82 elif key == "karaf_password":
83 self.karafPass = self.options[ key ]
84
Jeremy Ronquillo82705492017-10-18 14:19:55 -070085 self.home = self.checkOptions( self.home, "~/onos" )
86 self.karafUser = self.checkOptions( self.karafUser, self.user_name )
87 self.karafPass = self.checkOptions( self.karafPass, self.pwd )
andrewonlab95ce8322014-10-13 14:12:04 -040088
kelvin-onlaba4074292015-07-09 15:19:49 -070089 for key in self.options:
90 if key == 'onosIp':
91 self.onosIp = self.options[ 'onosIp' ]
92 break
93
kelvin8ec71442015-01-15 16:57:00 -080094 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070095
96 try:
Jon Hallc6793552016-01-19 14:18:37 -080097 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070098 self.ip_address = os.getenv( str( self.ip_address ) )
99 else:
100 main.log.info( self.name +
101 ": Trying to connect to " +
102 self.ip_address )
103
104 except KeyError:
105 main.log.info( "Invalid host name," +
106 " connecting to local host instead" )
107 self.ip_address = 'localhost'
108 except Exception as inst:
109 main.log.error( "Uncaught exception: " + str( inst ) )
110
kelvin8ec71442015-01-15 16:57:00 -0800111 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800112 user_name=self.user_name,
113 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800114 port=self.port,
115 pwd=self.pwd,
116 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400117
kelvin8ec71442015-01-15 16:57:00 -0800118 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700119 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400120 if self.handle:
121 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800122 else:
123 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400124 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800125 except TypeError:
126 main.log.exception( self.name + ": Object not as expected" )
127 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400128 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800129 main.log.error( self.name + ": EOF exception found" )
130 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700131 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800132 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800133 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700134 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400135
kelvin8ec71442015-01-15 16:57:00 -0800136 def disconnect( self ):
137 """
andrewonlab95ce8322014-10-13 14:12:04 -0400138 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800139 """
Jon Halld61331b2015-02-17 16:35:47 -0800140 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400141 try:
Jon Hall61282e32015-03-19 11:34:11 -0700142 if self.handle:
143 i = self.logout()
144 if i == main.TRUE:
145 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700146 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700147 self.handle.sendline( "exit" )
148 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800149 except TypeError:
150 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800151 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400152 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800153 main.log.error( self.name + ": EOF exception found" )
154 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700155 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700156 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700157 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800158 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800159 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400160 response = main.FALSE
161 return response
162
kelvin8ec71442015-01-15 16:57:00 -0800163 def logout( self ):
164 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500165 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700166 Returns main.TRUE if exited CLI and
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000167 main.FALSE on timeout (not guranteed you are disconnected)
Jon Hall61282e32015-03-19 11:34:11 -0700168 None on TypeError
169 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800170 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500171 try:
Jon Hall61282e32015-03-19 11:34:11 -0700172 if self.handle:
173 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700174 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ],
Jon Hall61282e32015-03-19 11:34:11 -0700175 timeout=10 )
176 if i == 0: # In ONOS CLI
177 self.handle.sendline( "logout" )
Devin Limdc78e202017-06-09 18:30:07 -0700178 j = self.handle.expect( [ self.prompt,
Jon Hallbfe00002016-04-05 10:23:54 -0700179 "Command not found:",
180 pexpect.TIMEOUT ] )
181 if j == 0: # Successfully logged out
182 return main.TRUE
183 elif j == 1 or j == 2:
184 # ONOS didn't fully load, and logout command isn't working
185 # or the command timed out
186 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700187 try:
Devin Limdc78e202017-06-09 18:30:07 -0700188 self.handle.expect( self.prompt )
Jon Hall64ab3bd2016-05-13 11:29:44 -0700189 except pexpect.TIMEOUT:
190 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700191 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700192 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700193 main.log.warn( "Unknown repsonse to logout command: '{}'",
194 repr( self.handle.before ) )
195 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700196 elif i == 1: # not in CLI
197 return main.TRUE
198 elif i == 3: # Timeout
199 return main.FALSE
200 else:
andrewonlab9627f432014-11-14 12:45:10 -0500201 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800202 except TypeError:
203 main.log.exception( self.name + ": Object not as expected" )
204 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500205 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800206 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700207 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700208 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700209 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700210 main.log.error( self.name +
211 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800212 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800213 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700214 main.cleanAndExit()
andrewonlab38d2b4a2014-11-13 16:28:47 -0500215
kelvin-onlabd3b64892015-01-20 13:26:24 -0800216 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800217 """
andrewonlab95ce8322014-10-13 14:12:04 -0400218 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800219
andrewonlab95ce8322014-10-13 14:12:04 -0400220 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800221 """
andrewonlab95ce8322014-10-13 14:12:04 -0400222 try:
223 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800224 main.log.error( "Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700225 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400226 else:
kelvin8ec71442015-01-15 16:57:00 -0800227 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800229 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400230 # and that this driver will have to change accordingly
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700231 self.handle.expect( str( cellname ) )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800232 handleBefore = self.handle.before
233 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800234 # Get the rest of the handle
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700235 self.handle.sendline( "" )
236 self.handle.expect( self.prompt )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800237 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400238
kelvin-onlabd3b64892015-01-20 13:26:24 -0800239 main.log.info( "Cell call returned: " + handleBefore +
240 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400241
242 return main.TRUE
243
Jon Halld4d4b372015-01-28 16:02:41 -0800244 except TypeError:
245 main.log.exception( self.name + ": Object not as expected" )
246 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400247 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800248 main.log.error( self.name + ": eof exception found" )
249 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700250 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800251 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800252 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700253 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -0800254
pingping-lin57a56ce2015-05-20 16:43:48 -0700255 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800256 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800257 """
Jon Hallefbd9792015-03-05 16:11:36 -0800258 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800259 by user would be used to set the current karaf shell idle timeout.
260 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800261 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800262 Below is an example to start a session with 60 seconds idle timeout
263 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800264
Hari Krishna25d42f72015-01-05 15:08:28 -0800265 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800266 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800267
kelvin-onlabd3b64892015-01-20 13:26:24 -0800268 Note: karafTimeout is left as str so that this could be read
269 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800270 """
You Wangf69ab392016-01-26 16:34:38 -0800271 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400272 try:
Jon Hall67253832016-12-05 09:47:13 -0800273 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800274 self.handle.sendline( "" )
275 x = self.handle.expect( [
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700276 self.prompt, "onos>" ], commandlineTimeout )
andrewonlab48829f62014-11-17 13:49:01 -0500277 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800278 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500279 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400280
Jon Hall67253832016-12-05 09:47:13 -0800281 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800282 if waitForStart:
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800283 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
284 startCliCommand = "onos-wait-for-start "
Chiyu Chengef109502016-11-21 15:51:38 -0800285 else:
286 startCliCommand = "onos "
287 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800288 i = self.handle.expect( [
289 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700290 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400291
292 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800293 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800294 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800295 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800296 "config:property-set -p org.apache.karaf.shell\
297 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800298 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700299 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800300 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800301 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400302 return main.TRUE
303 else:
kelvin8ec71442015-01-15 16:57:00 -0800304 # If failed, send ctrl+c to process and try again
305 main.log.info( "Starting CLI failed. Retrying..." )
306 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800307 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800308 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
309 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400310 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800311 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800312 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800313 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800314 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800315 "config:property-set -p org.apache.karaf.shell\
316 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800317 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700318 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800319 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800320 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400321 return main.TRUE
322 else:
kelvin8ec71442015-01-15 16:57:00 -0800323 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800324 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400325 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400326
Jon Halld4d4b372015-01-28 16:02:41 -0800327 except TypeError:
328 main.log.exception( self.name + ": Object not as expected" )
329 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400330 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800331 main.log.error( self.name + ": EOF exception found" )
332 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700333 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800334 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800335 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700336 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400337
suibin zhang116647a2016-05-06 16:30:09 -0700338 def startCellCli( self, karafTimeout="",
339 commandlineTimeout=10, onosStartTimeout=60 ):
340 """
341 Start CLI on onos ecll handle.
342
343 karafTimeout is an optional argument. karafTimeout value passed
344 by user would be used to set the current karaf shell idle timeout.
345 Note that when ever this property is modified the shell will exit and
346 the subsequent login would reflect new idle timeout.
347 Below is an example to start a session with 60 seconds idle timeout
348 ( input value is in milliseconds ):
349
350 tValue = "60000"
351
352 Note: karafTimeout is left as str so that this could be read
353 and passed to startOnosCli from PARAMS file as str.
354 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000355
suibin zhang116647a2016-05-06 16:30:09 -0700356 try:
357 self.handle.sendline( "" )
358 x = self.handle.expect( [
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700359 self.prompt, "onos>" ], commandlineTimeout )
suibin zhang116647a2016-05-06 16:30:09 -0700360
361 if x == 1:
362 main.log.info( "ONOS cli is already running" )
363 return main.TRUE
364
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800365 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
suibin zhang116647a2016-05-06 16:30:09 -0700366 self.handle.sendline( "/opt/onos/bin/onos" )
367 i = self.handle.expect( [
368 "onos>",
369 pexpect.TIMEOUT ], onosStartTimeout )
370
371 if i == 0:
372 main.log.info( self.name + " CLI Started successfully" )
373 if karafTimeout:
374 self.handle.sendline(
375 "config:property-set -p org.apache.karaf.shell\
376 sshIdleTimeout " +
377 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700378 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700379 self.handle.sendline( "/opt/onos/bin/onos" )
380 self.handle.expect( "onos>" )
381 return main.TRUE
382 else:
383 # If failed, send ctrl+c to process and try again
384 main.log.info( "Starting CLI failed. Retrying..." )
385 self.handle.send( "\x03" )
386 self.handle.sendline( "/opt/onos/bin/onos" )
387 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
388 timeout=30 )
389 if i == 0:
390 main.log.info( self.name + " CLI Started " +
391 "successfully after retry attempt" )
392 if karafTimeout:
393 self.handle.sendline(
394 "config:property-set -p org.apache.karaf.shell\
395 sshIdleTimeout " +
396 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700397 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700398 self.handle.sendline( "/opt/onos/bin/onos" )
399 self.handle.expect( "onos>" )
400 return main.TRUE
401 else:
402 main.log.error( "Connection to CLI " +
403 self.name + " timeout" )
404 return main.FALSE
405
406 except TypeError:
407 main.log.exception( self.name + ": Object not as expected" )
408 return None
409 except pexpect.EOF:
410 main.log.error( self.name + ": EOF exception found" )
411 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700412 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700413 except Exception:
414 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700415 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700416
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800417 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800418 """
419 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800420 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800421 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700422 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800423 Available level: DEBUG, TRACE, INFO, WARN, ERROR
424 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800425 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800426 """
427 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800428 lvlStr = ""
429 if level:
430 lvlStr = "--level=" + level
431
kelvin-onlab338f5512015-02-06 10:53:16 -0800432 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700433 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800434 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800435
kelvin-onlab9f541032015-02-04 16:19:53 -0800436 response = self.handle.before
437 if re.search( "Error", response ):
438 return main.FALSE
439 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700440 except pexpect.TIMEOUT:
441 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700442 if noExit:
443 main.cleanup()
444 return None
445 else:
Devin Lim44075962017-08-11 10:56:37 -0700446 main.cleanAndExit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800447 except pexpect.EOF:
448 main.log.error( self.name + ": EOF exception found" )
449 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700450 if noExit:
451 main.cleanup()
452 return None
453 else:
Devin Lim44075962017-08-11 10:56:37 -0700454 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800455 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800456 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700457 if noExit:
458 main.cleanup()
459 return None
460 else:
Devin Lim44075962017-08-11 10:56:37 -0700461 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400462
Jon Hall0e240372018-05-02 11:21:57 -0700463 def clearBuffer( self, debug=False, timeout=10, noExit=False ):
kelvin8ec71442015-01-15 16:57:00 -0800464 """
Jon Hall0e240372018-05-02 11:21:57 -0700465 Test cli connection and clear any left over output in the buffer
466 Optional Arguments:
467 debug - Defaults to False. If True, will enable debug logging.
468 timeout - Defaults to 10. Amount of time in seconds for a command to return
469 before a timeout.
470 noExit - Defaults to False. If True, will not exit TestON in the event of a
kelvin8ec71442015-01-15 16:57:00 -0800471 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400472 try:
Jon Halla495f562016-05-16 18:03:26 -0700473 # Try to reconnect if disconnected from cli
474 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700475 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ] )
Jon Hall0e240372018-05-02 11:21:57 -0700476 response = self.handle.before
Jon Halla495f562016-05-16 18:03:26 -0700477 if i == 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700478 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700479 if self.onosIp:
480 main.log.warn( "Trying to reconnect " + self.onosIp )
481 reconnectResult = self.startOnosCli( self.onosIp )
482 if reconnectResult:
483 main.log.info( self.name + ": onos cli session reconnected." )
484 else:
485 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700486 if noExit:
487 return None
488 else:
Devin Lim44075962017-08-11 10:56:37 -0700489 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700490 else:
Devin Lim44075962017-08-11 10:56:37 -0700491 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700492 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700493 main.log.warn( "Timeout when testing cli responsiveness" )
494 main.log.debug( self.handle.before )
495 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700496 self.handle.expect( "onos>" )
497
Jon Hall0e240372018-05-02 11:21:57 -0700498 response += self.handle.before
Jon Hall14a03b52016-05-11 12:07:30 -0700499 if debug:
Jon Hall0e240372018-05-02 11:21:57 -0700500 main.log.debug( self.name + ": Raw output from sending ''" )
501 main.log.debug( self.name + ": " + repr( response ) )
502 except pexpect.TIMEOUT:
503 main.log.error( self.name + ": ONOS timeout" )
504 main.log.debug( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700505 self.handle.send( "\x03" )
506 self.handle.expect( "onos>" )
Jon Hall0e240372018-05-02 11:21:57 -0700507 return None
508 except pexpect.EOF:
509 main.log.error( self.name + ": EOF exception found" )
510 main.log.error( self.name + ": " + self.handle.before )
511 if noExit:
512 return None
513 else:
514 main.cleanAndExit()
515 except Exception:
516 main.log.exception( self.name + ": Uncaught exception!" )
517 if noExit:
518 return None
519 else:
520 main.cleanAndExit()
521
522 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
523 """
524 A wrapper around pexpect's sendline/expect. Will return all the output from a given command
525
526 Required Arguments:
527 cmdStr - String to send to the pexpect session
528
529 Optional Arguments:
530 showResponse - Defaults to False. If True will log the response.
531 debug - Defaults to False. If True, will enable debug logging.
532 timeout - Defaults to 10. Amount of time in seconds for a command to return
533 before a timeout.
534 noExit - Defaults to False. If True, will not exit TestON in the event of a
535 closed channel, but instead return None
536
537 Warning: There are no sanity checking to commands sent using this method.
538
539 """
540 try:
541 # Try to reconnect if disconnected from cli
542 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
543 if debug:
544 # NOTE: This adds an average of .4 seconds per call
Jon Hall14a03b52016-05-11 12:07:30 -0700545 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700546 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800547 self.handle.sendline( cmdStr )
Jon Hall3e6edb32018-08-21 16:20:30 -0700548 self.handle.expect( "onos>", timeout )
Jon Hall63604932015-02-26 17:09:50 -0800549 response = self.handle.before
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000550 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800551 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700552 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700553 main.log.debug( self.name + ": Raw output" )
554 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700555
556 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800557 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800558 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700559 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700560 main.log.debug( self.name + ": ansiEscape output" )
561 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700562
kelvin-onlabfb521662015-02-27 09:52:40 -0800563 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000564 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700565 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700566 main.log.debug( self.name + ": Removed extra returns " +
567 "from output" )
568 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700569
570 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800571 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700572 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700573 main.log.debug( self.name + ": parsed and stripped output" )
574 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700575
Jon Hall63604932015-02-26 17:09:50 -0800576 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700577 output = response.split( cmdStr.strip(), 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700578 if output:
579 if debug:
580 main.log.debug( self.name + ": split output" )
581 for r in output:
582 main.log.debug( self.name + ": " + repr( r ) )
583 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800584 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800585 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700586 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800587 return output
GlennRCed771242016-01-13 17:02:47 -0800588 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700589 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800590 if debug:
591 main.log.debug( self.handle.before )
You Wang141b43b2018-06-26 16:50:18 -0700592 self.handle.send( "\x03" )
593 self.handle.expect( "onos>" )
GlennRCed771242016-01-13 17:02:47 -0800594 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700595 except IndexError:
596 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700597 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700598 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800599 except TypeError:
600 main.log.exception( self.name + ": Object not as expected" )
601 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400602 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800603 main.log.error( self.name + ": EOF exception found" )
604 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700605 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700606 return None
607 else:
Devin Lim44075962017-08-11 10:56:37 -0700608 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800609 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800610 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700611 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700612 return None
613 else:
Devin Lim44075962017-08-11 10:56:37 -0700614 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400615
kelvin8ec71442015-01-15 16:57:00 -0800616 # IMPORTANT NOTE:
617 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800618 # the cli command changing 'a:b' with 'aB'.
619 # Ex ) onos:topology > onosTopology
620 # onos:links > onosLinks
621 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800622
kelvin-onlabd3b64892015-01-20 13:26:24 -0800623 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800624 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400625 Adds a new cluster node by ID and address information.
626 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 * nodeId
628 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400629 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800630 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800631 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400632 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800633 cmdStr = "add-node " + str( nodeId ) + " " +\
634 str( ONOSIp ) + " " + str( tcpPort )
635 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700636 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800637 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800638 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700639 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800640 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800641 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400642 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800643 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400644 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800645 except AssertionError:
646 main.log.exception( "" )
647 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800648 except TypeError:
649 main.log.exception( self.name + ": Object not as expected" )
650 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400651 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800652 main.log.error( self.name + ": EOF exception found" )
653 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700654 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800655 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800656 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700657 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400658
kelvin-onlabd3b64892015-01-20 13:26:24 -0800659 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800660 """
andrewonlab86dc3082014-10-13 18:18:38 -0400661 Removes a cluster by ID
662 Issues command: 'remove-node [<node-id>]'
663 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800664 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800665 """
andrewonlab86dc3082014-10-13 18:18:38 -0400666 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400667
kelvin-onlabd3b64892015-01-20 13:26:24 -0800668 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700669 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700670 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800671 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700672 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700673 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700674 main.log.error( handle )
675 return main.FALSE
676 else:
677 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800678 except AssertionError:
679 main.log.exception( "" )
680 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800681 except TypeError:
682 main.log.exception( self.name + ": Object not as expected" )
683 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400684 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800685 main.log.error( self.name + ": EOF exception found" )
686 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700687 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800688 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800689 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700690 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400691
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700692 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800693 """
andrewonlab7c211572014-10-15 16:45:20 -0400694 List the nodes currently visible
695 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700696 Optional argument:
697 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800698 """
andrewonlab7c211572014-10-15 16:45:20 -0400699 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700700 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700701 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700702 cmdStr += " -j"
703 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700704 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800705 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700706 return output
Jon Hallc6793552016-01-19 14:18:37 -0800707 except AssertionError:
708 main.log.exception( "" )
709 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800710 except TypeError:
711 main.log.exception( self.name + ": Object not as expected" )
712 return None
andrewonlab7c211572014-10-15 16:45:20 -0400713 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800714 main.log.error( self.name + ": EOF exception found" )
715 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700716 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800717 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800718 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700719 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400720
kelvin8ec71442015-01-15 16:57:00 -0800721 def topology( self ):
722 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700723 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700724 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700725 Return:
726 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800727 """
andrewonlab95ce8322014-10-13 14:12:04 -0400728 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700729 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800730 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800731 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800732 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700733 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400734 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800735 except AssertionError:
736 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800737 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800738 except TypeError:
739 main.log.exception( self.name + ": Object not as expected" )
740 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400741 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800742 main.log.error( self.name + ": EOF exception found" )
743 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700744 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800745 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800746 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700747 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800748
jenkins7ead5a82015-03-13 10:28:21 -0700749 def deviceRemove( self, deviceId ):
750 """
751 Removes particular device from storage
752
753 TODO: refactor this function
754 """
755 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700756 cmdStr = "device-remove " + str( deviceId )
757 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800758 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800759 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700760 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700761 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700762 main.log.error( handle )
763 return main.FALSE
764 else:
765 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800766 except AssertionError:
767 main.log.exception( "" )
768 return None
jenkins7ead5a82015-03-13 10:28:21 -0700769 except TypeError:
770 main.log.exception( self.name + ": Object not as expected" )
771 return None
772 except pexpect.EOF:
773 main.log.error( self.name + ": EOF exception found" )
774 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700775 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700776 except Exception:
777 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700778 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700779
You Wang3b9689a2018-08-30 12:24:00 -0700780 def devices( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800781 """
Jon Hall7b02d952014-10-17 20:14:54 -0400782 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400783 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800784 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800785 """
andrewonlab86dc3082014-10-13 18:18:38 -0400786 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700787 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800788 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700789 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700790 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800791 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800792 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700793 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800794 except AssertionError:
795 main.log.exception( "" )
796 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800797 except TypeError:
798 main.log.exception( self.name + ": Object not as expected" )
799 return None
andrewonlab7c211572014-10-15 16:45:20 -0400800 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800801 main.log.error( self.name + ": EOF exception found" )
802 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700803 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800804 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800805 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700806 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400807
kelvin-onlabd3b64892015-01-20 13:26:24 -0800808 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800809 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800810 This balances the devices across all controllers
811 by issuing command: 'onos> onos:balance-masters'
812 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800813 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800814 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800815 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700816 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800817 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800818 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700819 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700820 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700821 main.log.error( handle )
822 return main.FALSE
823 else:
824 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800825 except AssertionError:
826 main.log.exception( "" )
827 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800828 except TypeError:
829 main.log.exception( self.name + ": Object not as expected" )
830 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800831 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800832 main.log.error( self.name + ": EOF exception found" )
833 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700834 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800835 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800836 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700837 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800838
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000839 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700840 """
841 Returns the output of the masters command.
842 Optional argument:
843 * jsonFormat - boolean indicating if you want output in json
844 """
845 try:
846 cmdStr = "onos:masters"
847 if jsonFormat:
848 cmdStr += " -j"
849 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700850 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800851 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700852 return output
Jon Hallc6793552016-01-19 14:18:37 -0800853 except AssertionError:
854 main.log.exception( "" )
855 return None
acsmars24950022015-07-30 18:00:43 -0700856 except TypeError:
857 main.log.exception( self.name + ": Object not as expected" )
858 return None
859 except pexpect.EOF:
860 main.log.error( self.name + ": EOF exception found" )
861 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700862 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700863 except Exception:
864 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700865 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700866
Jon Hallc6793552016-01-19 14:18:37 -0800867 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700868 """
869 Uses the master command to check that the devices' leadership
870 is evenly divided
871
872 Dependencies: checkMasters() and summary()
873
Jon Hall6509dbf2016-06-21 17:01:17 -0700874 Returns main.TRUE if the devices are balanced
875 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700876 Exits on Exception
877 Returns None on TypeError
878 """
879 try:
Jon Hallc6793552016-01-19 14:18:37 -0800880 summaryOutput = self.summary()
881 totalDevices = json.loads( summaryOutput )[ "devices" ]
882 except ( TypeError, ValueError ):
883 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
884 return None
885 try:
acsmars24950022015-07-30 18:00:43 -0700886 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800887 mastersOutput = self.checkMasters()
888 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700889 first = masters[ 0 ][ "size" ]
890 for master in masters:
891 totalOwnedDevices += master[ "size" ]
892 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
893 main.log.error( "Mastership not balanced" )
894 main.log.info( "\n" + self.checkMasters( False ) )
895 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700896 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700897 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700898 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800899 except ( TypeError, ValueError ):
900 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700901 return None
902 except pexpect.EOF:
903 main.log.error( self.name + ": EOF exception found" )
904 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700905 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700906 except Exception:
907 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700908 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700909
YPZhangfebf7302016-05-24 16:45:56 -0700910 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800911 """
Jon Halle8217482014-10-17 13:49:14 -0400912 Lists all core links
913 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800914 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800915 """
Jon Halle8217482014-10-17 13:49:14 -0400916 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700917 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800918 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700919 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700920 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800921 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800922 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700923 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800924 except AssertionError:
925 main.log.exception( "" )
926 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800927 except TypeError:
928 main.log.exception( self.name + ": Object not as expected" )
929 return None
Jon Halle8217482014-10-17 13:49:14 -0400930 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800931 main.log.error( self.name + ": EOF exception found" )
932 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700933 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800934 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800935 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700936 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400937
You Wang3b9689a2018-08-30 12:24:00 -0700938 def ports( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800939 """
Jon Halle8217482014-10-17 13:49:14 -0400940 Lists all ports
941 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800942 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800943 """
Jon Halle8217482014-10-17 13:49:14 -0400944 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700945 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800946 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700947 cmdStr += " -j"
You Wang3b9689a2018-08-30 12:24:00 -0700948 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800949 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800950 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700951 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800952 except AssertionError:
953 main.log.exception( "" )
954 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800955 except TypeError:
956 main.log.exception( self.name + ": Object not as expected" )
957 return None
Jon Halle8217482014-10-17 13:49:14 -0400958 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800959 main.log.error( self.name + ": EOF exception found" )
960 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700961 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800962 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800963 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700964 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400965
kelvin-onlabd3b64892015-01-20 13:26:24 -0800966 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800967 """
Jon Hall983a1702014-10-28 18:44:22 -0400968 Lists all devices and the controllers with roles assigned to them
969 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800970 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800971 """
andrewonlab7c211572014-10-15 16:45:20 -0400972 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700973 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800974 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700975 cmdStr += " -j"
976 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800977 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800978 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700979 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800980 except AssertionError:
981 main.log.exception( "" )
982 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800983 except TypeError:
984 main.log.exception( self.name + ": Object not as expected" )
985 return None
Jon Hall983a1702014-10-28 18:44:22 -0400986 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800987 main.log.error( self.name + ": EOF exception found" )
988 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700989 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800990 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800991 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700992 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -0400993
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800995 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800996 Given the a string containing the json representation of the "roles"
997 cli command and a partial or whole device id, returns a json object
998 containing the roles output for the first device whose id contains
999 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -04001000
1001 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001002 A dict of the role assignments for the given device or
1003 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001004 """
Jon Hall983a1702014-10-28 18:44:22 -04001005 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001006 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001007 return None
1008 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001009 rawRoles = self.roles()
1010 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001011 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001012 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001013 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001015 return device
1016 return None
Jon Hallc6793552016-01-19 14:18:37 -08001017 except ( TypeError, ValueError ):
1018 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001019 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001020 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001021 main.log.error( self.name + ": EOF exception found" )
1022 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001023 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001024 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001025 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001026 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001027
kelvin-onlabd3b64892015-01-20 13:26:24 -08001028 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001029 """
Jon Hall94fd0472014-12-08 11:52:42 -08001030 Iterates through each device and checks if there is a master assigned
1031 Returns: main.TRUE if each device has a master
1032 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001033 """
Jon Hall94fd0472014-12-08 11:52:42 -08001034 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001035 rawRoles = self.roles()
1036 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001037 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001038 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001039 # print device
1040 if device[ 'master' ] == "none":
1041 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001042 return main.FALSE
1043 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001044 except ( TypeError, ValueError ):
1045 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001046 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001047 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001048 main.log.error( self.name + ": EOF exception found" )
1049 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001050 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001051 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001052 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001053 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001054
kelvin-onlabd3b64892015-01-20 13:26:24 -08001055 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001056 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001057 Returns string of paths, and the cost.
1058 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001059 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001060 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001061 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1062 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001063 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001064 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001065 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001066 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001067 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001068 else:
kelvin8ec71442015-01-15 16:57:00 -08001069 path = handle.split( ";" )[ 0 ]
1070 cost = handle.split( ";" )[ 1 ]
1071 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001072 except AssertionError:
1073 main.log.exception( "" )
1074 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001075 except TypeError:
1076 main.log.exception( self.name + ": Object not as expected" )
1077 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001078 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001079 main.log.error( self.name + ": EOF exception found" )
1080 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001081 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001082 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001083 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001084 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001085
kelvin-onlabd3b64892015-01-20 13:26:24 -08001086 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001087 """
Jon Hallffb386d2014-11-21 13:43:38 -08001088 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001089 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001090 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001091 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001092 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001093 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001094 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001095 cmdStr += " -j"
1096 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001097 if handle:
1098 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001099 # TODO: Maybe make this less hardcoded
1100 # ConsistentMap Exceptions
1101 assert "org.onosproject.store.service" not in handle
1102 # Node not leader
1103 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001104 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001105 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001106 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001107 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001108 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001109 except TypeError:
1110 main.log.exception( self.name + ": Object not as expected" )
1111 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001112 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001113 main.log.error( self.name + ": EOF exception found" )
1114 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001115 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001116 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001117 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001118 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001119
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001121 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001122 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001123
Jon Hallefbd9792015-03-05 16:11:36 -08001124 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001125 partial mac address
1126
Jon Hall42db6dc2014-10-24 19:03:48 -04001127 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001128 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001129 try:
kelvin8ec71442015-01-15 16:57:00 -08001130 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001131 return None
1132 else:
1133 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 rawHosts = self.hosts()
1135 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001136 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001137 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001138 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001139 if not host:
1140 pass
1141 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001142 return host
1143 return None
Jon Hallc6793552016-01-19 14:18:37 -08001144 except ( TypeError, ValueError ):
1145 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001146 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001147 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001148 main.log.error( self.name + ": EOF exception found" )
1149 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001150 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001151 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001152 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001153 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001154
kelvin-onlabd3b64892015-01-20 13:26:24 -08001155 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001156 """
1157 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001158 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001159
andrewonlab3f0a4af2014-10-17 12:25:14 -04001160 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001161 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001162 IMPORTANT:
1163 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001164 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001165 Furthermore, it assumes that value of VLAN is '-1'
1166 Description:
kelvin8ec71442015-01-15 16:57:00 -08001167 Converts mininet hosts ( h1, h2, h3... ) into
1168 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1169 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001170 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001171 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001172
kelvin-onlabd3b64892015-01-20 13:26:24 -08001173 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001174 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001175 hostHex = hex( int( host ) ).zfill( 12 )
1176 hostHex = str( hostHex ).replace( 'x', '0' )
1177 i = iter( str( hostHex ) )
1178 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1179 hostHex = hostHex + "/-1"
1180 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001181
kelvin-onlabd3b64892015-01-20 13:26:24 -08001182 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001183
Jon Halld4d4b372015-01-28 16:02:41 -08001184 except TypeError:
1185 main.log.exception( self.name + ": Object not as expected" )
1186 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001187 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001188 main.log.error( self.name + ": EOF exception found" )
1189 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001190 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001191 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001192 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001193 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001194
You Wangbc898b82018-05-03 16:22:34 -07001195 def verifyHostLocation( self, hostIp, location ):
1196 """
1197 Description:
1198 Verify the host given is discovered in all locations expected
1199 Required:
1200 hostIp: IP address of the host
1201 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1202 Could be a string or list
1203 Returns:
1204 main.TRUE if host is discovered on all locations provided
1205 main.FALSE otherwise
1206 """
1207 import json
1208 locations = [ location ] if isinstance( location, str ) else location
1209 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1210 try:
1211 hosts = self.hosts()
1212 hosts = json.loads( hosts )
1213 targetHost = None
1214 for host in hosts:
1215 if hostIp in host[ "ipAddresses" ]:
1216 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001217 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001218 result = main.TRUE
1219 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1220 for loc in locations:
1221 discovered = False
1222 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001223 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1224 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001225 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001226 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001227 break
1228 if discovered:
1229 locationsDiscovered.remove( locDiscovered )
1230 else:
1231 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1232 result = main.FALSE
1233 if locationsDiscovered:
1234 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1235 result = main.FALSE
1236 return result
1237 except KeyError:
1238 main.log.exception( self.name + ": host data not as expected: " + hosts )
1239 return None
1240 except pexpect.EOF:
1241 main.log.error( self.name + ": EOF exception found" )
1242 main.log.error( self.name + ": " + self.handle.before )
1243 main.cleanAndExit()
1244 except Exception:
1245 main.log.exception( self.name + ": Uncaught exception" )
1246 return None
1247
You Wang53dba1e2018-02-02 17:45:44 -08001248 def verifyHostIp( self, hostList=[], prefix="" ):
1249 """
1250 Description:
1251 Verify that all hosts have IP address assigned to them
1252 Optional:
1253 hostList: If specified, verifications only happen to the hosts
1254 in hostList
1255 prefix: at least one of the ip address assigned to the host
1256 needs to have the specified prefix
1257 Returns:
1258 main.TRUE if all hosts have specific IP address assigned;
1259 main.FALSE otherwise
1260 """
1261 import json
1262 try:
1263 hosts = self.hosts()
1264 hosts = json.loads( hosts )
1265 if not hostList:
1266 hostList = [ host[ "id" ] for host in hosts ]
1267 for host in hosts:
1268 hostId = host[ "id" ]
1269 if hostId not in hostList:
1270 continue
1271 ipList = host[ "ipAddresses" ]
1272 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1273 if not ipList:
1274 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1275 else:
1276 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1277 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1278 else:
1279 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1280 hostList.remove( hostId )
1281 if hostList:
1282 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1283 return main.FALSE
1284 else:
1285 return main.TRUE
1286 except KeyError:
1287 main.log.exception( self.name + ": host data not as expected: " + hosts )
1288 return None
1289 except pexpect.EOF:
1290 main.log.error( self.name + ": EOF exception found" )
1291 main.log.error( self.name + ": " + self.handle.before )
1292 main.cleanAndExit()
1293 except Exception:
1294 main.log.exception( self.name + ": Uncaught exception" )
1295 return None
1296
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001297 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001298 """
andrewonlabe6745342014-10-17 14:29:13 -04001299 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001300 * hostIdOne: ONOS host id for host1
1301 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001302 Optional:
1303 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001304 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001305 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001306 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001307 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001308 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001309 Returns:
1310 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001311 """
andrewonlabe6745342014-10-17 14:29:13 -04001312 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001313 cmdStr = "add-host-intent "
1314 if vlanId:
1315 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001316 if setVlan:
1317 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001318 if encap:
1319 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001320 if bandwidth:
1321 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001322 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001323 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001324 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001325 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001326 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001327 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001328 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001329 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001330 else:
1331 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001332 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001333 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001334 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001335 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001336 else:
1337 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001338 main.log.debug( "Response from ONOS was: " +
1339 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001340 return None
Jon Hallc6793552016-01-19 14:18:37 -08001341 except AssertionError:
1342 main.log.exception( "" )
1343 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001344 except TypeError:
1345 main.log.exception( self.name + ": Object not as expected" )
1346 return None
andrewonlabe6745342014-10-17 14:29:13 -04001347 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001348 main.log.error( self.name + ": EOF exception found" )
1349 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001350 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001351 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001352 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001353 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001354
kelvin-onlabd3b64892015-01-20 13:26:24 -08001355 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001356 """
andrewonlab7b31d232014-10-24 13:31:47 -04001357 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001358 * ingressDevice: device id of ingress device
1359 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001360 Optional:
1361 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001362 Description:
1363 Adds an optical intent by specifying an ingress and egress device
1364 Returns:
1365 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001366 """
andrewonlab7b31d232014-10-24 13:31:47 -04001367 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001368 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1369 " " + str( egressDevice )
1370 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001371 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001372 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001373 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001374 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001375 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001376 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001377 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001378 main.log.info( "Optical intent installed between " +
1379 str( ingressDevice ) + " and " +
1380 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001381 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001382 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001383 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001384 else:
1385 main.log.error( "Error, intent ID not found" )
1386 return None
Jon Hallc6793552016-01-19 14:18:37 -08001387 except AssertionError:
1388 main.log.exception( "" )
1389 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001390 except TypeError:
1391 main.log.exception( self.name + ": Object not as expected" )
1392 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001393 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001394 main.log.error( self.name + ": EOF exception found" )
1395 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001396 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001397 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001398 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001399 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001400
kelvin-onlabd3b64892015-01-20 13:26:24 -08001401 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001402 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001403 ingressDevice,
1404 egressDevice,
1405 portIngress="",
1406 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001407 ethType="",
1408 ethSrc="",
1409 ethDst="",
1410 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001411 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001412 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001413 ipProto="",
1414 ipSrc="",
1415 ipDst="",
1416 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001417 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001418 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001419 setVlan="",
1420 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001421 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001422 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001423 * ingressDevice: device id of ingress device
1424 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001425 Optional:
1426 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001427 * ethSrc: specify ethSrc ( i.e. src mac addr )
1428 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001429 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001430 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001431 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001432 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001433 * ipSrc: specify ip source address
1434 * ipDst: specify ip destination address
1435 * tcpSrc: specify tcp source port
1436 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001437 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001438 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001439 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001440 Description:
kelvin8ec71442015-01-15 16:57:00 -08001441 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001442 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001443 Returns:
1444 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001445
Jon Halle3f39ff2015-01-13 11:50:53 -08001446 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001447 options developers provide for point-to-point
1448 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001449 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001450 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001451 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001452
Jeremy Songsterff553672016-05-12 17:06:23 -07001453 if ethType:
1454 cmd += " --ethType " + str( ethType )
1455 if ethSrc:
1456 cmd += " --ethSrc " + str( ethSrc )
1457 if ethDst:
1458 cmd += " --ethDst " + str( ethDst )
1459 if bandwidth:
1460 cmd += " --bandwidth " + str( bandwidth )
1461 if lambdaAlloc:
1462 cmd += " --lambda "
1463 if ipProto:
1464 cmd += " --ipProto " + str( ipProto )
1465 if ipSrc:
1466 cmd += " --ipSrc " + str( ipSrc )
1467 if ipDst:
1468 cmd += " --ipDst " + str( ipDst )
1469 if tcpSrc:
1470 cmd += " --tcpSrc " + str( tcpSrc )
1471 if tcpDst:
1472 cmd += " --tcpDst " + str( tcpDst )
1473 if vlanId:
1474 cmd += " -v " + str( vlanId )
1475 if setVlan:
1476 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001477 if encap:
1478 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001479 if protected:
1480 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001481
kelvin8ec71442015-01-15 16:57:00 -08001482 # Check whether the user appended the port
1483 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001484 if "/" in ingressDevice:
1485 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001486 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001487 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001488 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001489 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001490 # Would it make sense to throw an exception and exit
1491 # the test?
1492 return None
andrewonlab36af3822014-11-18 17:48:18 -05001493
kelvin8ec71442015-01-15 16:57:00 -08001494 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001495 str( ingressDevice ) + "/" +\
1496 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001497
kelvin-onlabd3b64892015-01-20 13:26:24 -08001498 if "/" in egressDevice:
1499 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001500 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001501 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001502 main.log.error( "You must specify the egress port" )
1503 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001504
kelvin8ec71442015-01-15 16:57:00 -08001505 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001506 str( egressDevice ) + "/" +\
1507 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001508
kelvin-onlab898a6c62015-01-16 14:13:53 -08001509 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001510 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001511 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001512 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001513 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001514 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001515 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001516 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001517 # TODO: print out all the options in this message?
1518 main.log.info( "Point-to-point intent installed between " +
1519 str( ingressDevice ) + " and " +
1520 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001521 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001522 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001523 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001524 else:
1525 main.log.error( "Error, intent ID not found" )
1526 return None
Jon Hallc6793552016-01-19 14:18:37 -08001527 except AssertionError:
1528 main.log.exception( "" )
1529 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001530 except TypeError:
1531 main.log.exception( self.name + ": Object not as expected" )
1532 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001533 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001534 main.log.error( self.name + ": EOF exception found" )
1535 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001536 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001537 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001538 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001539 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001540
kelvin-onlabd3b64892015-01-20 13:26:24 -08001541 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001542 self,
shahshreyac2f97072015-03-19 17:04:29 -07001543 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001544 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001545 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001546 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001547 ethType="",
1548 ethSrc="",
1549 ethDst="",
1550 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001551 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001552 ipProto="",
1553 ipSrc="",
1554 ipDst="",
1555 tcpSrc="",
1556 tcpDst="",
1557 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001558 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001559 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001560 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001561 partial=False,
1562 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001563 """
shahshreyad0c80432014-12-04 16:56:05 -08001564 Note:
shahshreya70622b12015-03-19 17:19:00 -07001565 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001566 is same. That is, all ingress devices include port numbers
1567 with a "/" or all ingress devices could specify device
1568 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001569 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001570 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001571 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001572 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001573 Optional:
1574 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001575 * ethSrc: specify ethSrc ( i.e. src mac addr )
1576 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001577 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001578 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001579 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001580 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001581 * ipSrc: specify ip source address
1582 * ipDst: specify ip destination address
1583 * tcpSrc: specify tcp source port
1584 * tcpDst: specify tcp destination port
1585 * setEthSrc: action to Rewrite Source MAC Address
1586 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001587 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001588 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001589 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001590 Description:
kelvin8ec71442015-01-15 16:57:00 -08001591 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001592 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001593 Returns:
1594 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001595
Jon Halle3f39ff2015-01-13 11:50:53 -08001596 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001597 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001598 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001599 """
shahshreyad0c80432014-12-04 16:56:05 -08001600 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001601 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001602
Jeremy Songsterff553672016-05-12 17:06:23 -07001603 if ethType:
1604 cmd += " --ethType " + str( ethType )
1605 if ethSrc:
1606 cmd += " --ethSrc " + str( ethSrc )
1607 if ethDst:
1608 cmd += " --ethDst " + str( ethDst )
1609 if bandwidth:
1610 cmd += " --bandwidth " + str( bandwidth )
1611 if lambdaAlloc:
1612 cmd += " --lambda "
1613 if ipProto:
1614 cmd += " --ipProto " + str( ipProto )
1615 if ipSrc:
1616 cmd += " --ipSrc " + str( ipSrc )
1617 if ipDst:
1618 cmd += " --ipDst " + str( ipDst )
1619 if tcpSrc:
1620 cmd += " --tcpSrc " + str( tcpSrc )
1621 if tcpDst:
1622 cmd += " --tcpDst " + str( tcpDst )
1623 if setEthSrc:
1624 cmd += " --setEthSrc " + str( setEthSrc )
1625 if setEthDst:
1626 cmd += " --setEthDst " + str( setEthDst )
1627 if vlanId:
1628 cmd += " -v " + str( vlanId )
1629 if setVlan:
1630 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001631 if partial:
1632 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001633 if encap:
1634 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001635
kelvin8ec71442015-01-15 16:57:00 -08001636 # Check whether the user appended the port
1637 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001638
1639 if portIngressList is None:
1640 for ingressDevice in ingressDeviceList:
1641 if "/" in ingressDevice:
1642 cmd += " " + str( ingressDevice )
1643 else:
1644 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001645 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001646 # TODO: perhaps more meaningful return
1647 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001648 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001649 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001650 for ingressDevice, portIngress in zip( ingressDeviceList,
1651 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001652 cmd += " " + \
1653 str( ingressDevice ) + "/" +\
1654 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001655 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001656 main.log.error( "Device list and port list does not " +
1657 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001658 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001659 if "/" in egressDevice:
1660 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001661 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001662 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001663 main.log.error( "You must specify " +
1664 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001665 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001666
kelvin8ec71442015-01-15 16:57:00 -08001667 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001668 str( egressDevice ) + "/" +\
1669 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001670 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001671 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001672 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001673 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001674 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001675 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001676 "intent" )
1677 return None
shahshreyad0c80432014-12-04 16:56:05 -08001678 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001679 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001680 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001681 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001682 else:
1683 main.log.error( "Error, intent ID not found" )
1684 return None
Jon Hallc6793552016-01-19 14:18:37 -08001685 except AssertionError:
1686 main.log.exception( "" )
1687 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001688 except TypeError:
1689 main.log.exception( self.name + ": Object not as expected" )
1690 return None
1691 except pexpect.EOF:
1692 main.log.error( self.name + ": EOF exception found" )
1693 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001694 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001695 except Exception:
1696 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001697 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001698
1699 def addSinglepointToMultipointIntent(
1700 self,
1701 ingressDevice,
1702 egressDeviceList,
1703 portIngress="",
1704 portEgressList=None,
1705 ethType="",
1706 ethSrc="",
1707 ethDst="",
1708 bandwidth="",
1709 lambdaAlloc=False,
1710 ipProto="",
1711 ipSrc="",
1712 ipDst="",
1713 tcpSrc="",
1714 tcpDst="",
1715 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001716 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001717 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001718 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001719 partial=False,
1720 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001721 """
1722 Note:
1723 This function assumes the format of all egress devices
1724 is same. That is, all egress devices include port numbers
1725 with a "/" or all egress devices could specify device
1726 ids and port numbers seperately.
1727 Required:
1728 * EgressDeviceList: List of device ids of egress device
1729 ( Atleast 2 eress devices required in the list )
1730 * ingressDevice: device id of ingress device
1731 Optional:
1732 * ethType: specify ethType
1733 * ethSrc: specify ethSrc ( i.e. src mac addr )
1734 * ethDst: specify ethDst ( i.e. dst mac addr )
1735 * bandwidth: specify bandwidth capacity of link
1736 * lambdaAlloc: if True, intent will allocate lambda
1737 for the specified intent
1738 * ipProto: specify ip protocol
1739 * ipSrc: specify ip source address
1740 * ipDst: specify ip destination address
1741 * tcpSrc: specify tcp source port
1742 * tcpDst: specify tcp destination port
1743 * setEthSrc: action to Rewrite Source MAC Address
1744 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001745 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001746 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001747 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001748 Description:
1749 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1750 specifying device id's and optional fields
1751 Returns:
1752 A string of the intent id or None on error
1753
1754 NOTE: This function may change depending on the
1755 options developers provide for singlepoint-to-multipoint
1756 intent via cli
1757 """
1758 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001759 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001760
Jeremy Songsterff553672016-05-12 17:06:23 -07001761 if ethType:
1762 cmd += " --ethType " + str( ethType )
1763 if ethSrc:
1764 cmd += " --ethSrc " + str( ethSrc )
1765 if ethDst:
1766 cmd += " --ethDst " + str( ethDst )
1767 if bandwidth:
1768 cmd += " --bandwidth " + str( bandwidth )
1769 if lambdaAlloc:
1770 cmd += " --lambda "
1771 if ipProto:
1772 cmd += " --ipProto " + str( ipProto )
1773 if ipSrc:
1774 cmd += " --ipSrc " + str( ipSrc )
1775 if ipDst:
1776 cmd += " --ipDst " + str( ipDst )
1777 if tcpSrc:
1778 cmd += " --tcpSrc " + str( tcpSrc )
1779 if tcpDst:
1780 cmd += " --tcpDst " + str( tcpDst )
1781 if setEthSrc:
1782 cmd += " --setEthSrc " + str( setEthSrc )
1783 if setEthDst:
1784 cmd += " --setEthDst " + str( setEthDst )
1785 if vlanId:
1786 cmd += " -v " + str( vlanId )
1787 if setVlan:
1788 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001789 if partial:
1790 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001791 if encap:
1792 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001793
1794 # Check whether the user appended the port
1795 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001796
kelvin-onlabb9408212015-04-01 13:34:04 -07001797 if "/" in ingressDevice:
1798 cmd += " " + str( ingressDevice )
1799 else:
1800 if not portIngress:
1801 main.log.error( "You must specify " +
1802 "the Ingress port" )
1803 return main.FALSE
1804
1805 cmd += " " +\
1806 str( ingressDevice ) + "/" +\
1807 str( portIngress )
1808
1809 if portEgressList is None:
1810 for egressDevice in egressDeviceList:
1811 if "/" in egressDevice:
1812 cmd += " " + str( egressDevice )
1813 else:
1814 main.log.error( "You must specify " +
1815 "the egress port" )
1816 # TODO: perhaps more meaningful return
1817 return main.FALSE
1818 else:
1819 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001820 for egressDevice, portEgress in zip( egressDeviceList,
1821 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001822 cmd += " " + \
1823 str( egressDevice ) + "/" +\
1824 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001825 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001826 main.log.error( "Device list and port list does not " +
1827 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001828 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001829 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001830 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001831 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001832 # If error, return error message
1833 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001834 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001835 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001836 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001837 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001838 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001839 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001840 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001841 else:
1842 main.log.error( "Error, intent ID not found" )
1843 return None
Jon Hallc6793552016-01-19 14:18:37 -08001844 except AssertionError:
1845 main.log.exception( "" )
1846 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001847 except TypeError:
1848 main.log.exception( self.name + ": Object not as expected" )
1849 return None
shahshreyad0c80432014-12-04 16:56:05 -08001850 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001851 main.log.error( self.name + ": EOF exception found" )
1852 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001853 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001854 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001855 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001856 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001857
Hari Krishna9e232602015-04-13 17:29:08 -07001858 def addMplsIntent(
1859 self,
1860 ingressDevice,
1861 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001862 ingressPort="",
1863 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001864 ethType="",
1865 ethSrc="",
1866 ethDst="",
1867 bandwidth="",
1868 lambdaAlloc=False,
1869 ipProto="",
1870 ipSrc="",
1871 ipDst="",
1872 tcpSrc="",
1873 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001874 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001875 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001876 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001877 """
1878 Required:
1879 * ingressDevice: device id of ingress device
1880 * egressDevice: device id of egress device
1881 Optional:
1882 * ethType: specify ethType
1883 * ethSrc: specify ethSrc ( i.e. src mac addr )
1884 * ethDst: specify ethDst ( i.e. dst mac addr )
1885 * bandwidth: specify bandwidth capacity of link
1886 * lambdaAlloc: if True, intent will allocate lambda
1887 for the specified intent
1888 * ipProto: specify ip protocol
1889 * ipSrc: specify ip source address
1890 * ipDst: specify ip destination address
1891 * tcpSrc: specify tcp source port
1892 * tcpDst: specify tcp destination port
1893 * ingressLabel: Ingress MPLS label
1894 * egressLabel: Egress MPLS label
1895 Description:
1896 Adds MPLS intent by
1897 specifying device id's and optional fields
1898 Returns:
1899 A string of the intent id or None on error
1900
1901 NOTE: This function may change depending on the
1902 options developers provide for MPLS
1903 intent via cli
1904 """
1905 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001906 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001907
Jeremy Songsterff553672016-05-12 17:06:23 -07001908 if ethType:
1909 cmd += " --ethType " + str( ethType )
1910 if ethSrc:
1911 cmd += " --ethSrc " + str( ethSrc )
1912 if ethDst:
1913 cmd += " --ethDst " + str( ethDst )
1914 if bandwidth:
1915 cmd += " --bandwidth " + str( bandwidth )
1916 if lambdaAlloc:
1917 cmd += " --lambda "
1918 if ipProto:
1919 cmd += " --ipProto " + str( ipProto )
1920 if ipSrc:
1921 cmd += " --ipSrc " + str( ipSrc )
1922 if ipDst:
1923 cmd += " --ipDst " + str( ipDst )
1924 if tcpSrc:
1925 cmd += " --tcpSrc " + str( tcpSrc )
1926 if tcpDst:
1927 cmd += " --tcpDst " + str( tcpDst )
1928 if ingressLabel:
1929 cmd += " --ingressLabel " + str( ingressLabel )
1930 if egressLabel:
1931 cmd += " --egressLabel " + str( egressLabel )
1932 if priority:
1933 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001934
1935 # Check whether the user appended the port
1936 # or provided it as an input
1937 if "/" in ingressDevice:
1938 cmd += " " + str( ingressDevice )
1939 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001940 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001941 main.log.error( "You must specify the ingress port" )
1942 return None
1943
1944 cmd += " " + \
1945 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001946 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001947
1948 if "/" in egressDevice:
1949 cmd += " " + str( egressDevice )
1950 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001951 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001952 main.log.error( "You must specify the egress port" )
1953 return None
1954
1955 cmd += " " +\
1956 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001957 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001958
1959 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001960 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001961 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001962 # If error, return error message
1963 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001964 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07001965 return None
1966 else:
1967 # TODO: print out all the options in this message?
1968 main.log.info( "MPLS intent installed between " +
1969 str( ingressDevice ) + " and " +
1970 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001971 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07001972 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001973 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07001974 else:
1975 main.log.error( "Error, intent ID not found" )
1976 return None
Jon Hallc6793552016-01-19 14:18:37 -08001977 except AssertionError:
1978 main.log.exception( "" )
1979 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001980 except TypeError:
1981 main.log.exception( self.name + ": Object not as expected" )
1982 return None
1983 except pexpect.EOF:
1984 main.log.error( self.name + ": EOF exception found" )
1985 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001986 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001987 except Exception:
1988 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001989 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001990
Jon Hallefbd9792015-03-05 16:11:36 -08001991 def removeIntent( self, intentId, app='org.onosproject.cli',
1992 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001993 """
shahshreya1c818fc2015-02-26 13:44:08 -08001994 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001995 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001996 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001997 -p or --purge: Purge the intent from the store after removal
1998
Jon Halle3f39ff2015-01-13 11:50:53 -08001999 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07002000 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08002001 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08002002 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002003 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002004 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002005 if purge:
2006 cmdStr += " -p"
2007 if sync:
2008 cmdStr += " -s"
2009
2010 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002011 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002012 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002013 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002014 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002015 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002016 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002017 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002018 # TODO: Should this be main.TRUE
2019 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002020 except AssertionError:
2021 main.log.exception( "" )
2022 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002023 except TypeError:
2024 main.log.exception( self.name + ": Object not as expected" )
2025 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002026 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002027 main.log.error( self.name + ": EOF exception found" )
2028 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002029 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002030 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002031 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002032 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002033
YPZhangfebf7302016-05-24 16:45:56 -07002034 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002035 """
2036 Description:
2037 Remove all the intents
2038 Optional args:-
2039 -s or --sync: Waits for the removal before returning
2040 -p or --purge: Purge the intent from the store after removal
2041 Returns:
2042 Returns main.TRUE if all intents are removed, otherwise returns
2043 main.FALSE; Returns None for exception
2044 """
2045 try:
2046 cmdStr = "remove-intent"
2047 if purge:
2048 cmdStr += " -p"
2049 if sync:
2050 cmdStr += " -s"
2051
2052 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002053 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002054 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002055 assert "Command not found:" not in handle, handle
2056 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002057 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002058 return main.FALSE
2059 else:
2060 return main.TRUE
2061 except AssertionError:
2062 main.log.exception( "" )
2063 return None
2064 except TypeError:
2065 main.log.exception( self.name + ": Object not as expected" )
2066 return None
2067 except pexpect.EOF:
2068 main.log.error( self.name + ": EOF exception found" )
2069 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002070 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002071 except Exception:
2072 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002073 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002074
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002075 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002076 """
2077 Purges all WITHDRAWN Intents
2078 """
2079 try:
2080 cmdStr = "purge-intents"
2081 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002082 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002083 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002084 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002085 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002086 return main.FALSE
2087 else:
2088 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002089 except AssertionError:
2090 main.log.exception( "" )
2091 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002092 except TypeError:
2093 main.log.exception( self.name + ": Object not as expected" )
2094 return None
2095 except pexpect.EOF:
2096 main.log.error( self.name + ": EOF exception found" )
2097 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002098 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002099 except Exception:
2100 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002101 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002102
Devin Lime6fe3c42017-10-18 16:28:40 -07002103 def wipeout( self ):
2104 """
2105 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2106 """
2107 try:
2108 cmdStr = "wipe-out please"
2109 handle = self.sendline( cmdStr, timeout=60 )
2110 assert handle is not None, "Error in sendline"
2111 assert "Command not found:" not in handle, handle
2112 return main.TRUE
2113 except AssertionError:
2114 main.log.exception( "" )
2115 return None
2116 except TypeError:
2117 main.log.exception( self.name + ": Object not as expected" )
2118 return None
2119 except pexpect.EOF:
2120 main.log.error( self.name + ": EOF exception found" )
2121 main.log.error( self.name + ": " + self.handle.before )
2122 main.cleanAndExit()
2123 except Exception:
2124 main.log.exception( self.name + ": Uncaught exception!" )
2125 main.cleanAndExit()
2126
kelvin-onlabd3b64892015-01-20 13:26:24 -08002127 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002128 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002129 NOTE: This method should be used after installing application:
2130 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002131 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002132 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002133 Description:
2134 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002135 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002136 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002137 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002138 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002139 cmdStr += " -j"
2140 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002141 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002142 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002143 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002144 except AssertionError:
2145 main.log.exception( "" )
2146 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002147 except TypeError:
2148 main.log.exception( self.name + ": Object not as expected" )
2149 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002150 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002151 main.log.error( self.name + ": EOF exception found" )
2152 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002153 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002154 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002155 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002156 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002157
pingping-lin54b03372015-08-13 14:43:10 -07002158 def ipv4RouteNumber( self ):
2159 """
2160 NOTE: This method should be used after installing application:
2161 onos-app-sdnip
2162 Description:
2163 Obtain the total IPv4 routes number in the system
2164 """
2165 try:
Pratik Parab57963572017-05-09 11:37:54 -07002166 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002167 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002168 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002169 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002170 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002171 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002172 except AssertionError:
2173 main.log.exception( "" )
2174 return None
2175 except ( TypeError, ValueError ):
2176 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002177 return None
2178 except pexpect.EOF:
2179 main.log.error( self.name + ": EOF exception found" )
2180 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002181 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002182 except Exception:
2183 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002184 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002185
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002186 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002187 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002188 """
2189 Description:
2190 Obtain Bandwidth Allocation Information from ONOS cli.
2191 """
2192 try:
2193 cmdStr = "allocations"
2194 if jsonFormat:
2195 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002196 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002197 assert handle is not None, "Error in sendline"
2198 assert "Command not found:" not in handle, handle
2199 return handle
2200 except AssertionError:
2201 main.log.exception( "" )
2202 return None
2203 except ( TypeError, ValueError ):
2204 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2205 return None
2206 except pexpect.EOF:
2207 main.log.error( self.name + ": EOF exception found" )
2208 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002209 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002210 except Exception:
2211 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002212 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002213
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002214 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002215 """
andrewonlabe6745342014-10-17 14:29:13 -04002216 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002217 Obtain intents from the ONOS cli.
2218 Optional:
2219 * jsonFormat: Enable output formatting in json, default to True
2220 * summary: Whether only output the intent summary, defaults to False
2221 * type: Only output a certain type of intent. This options is valid
2222 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002223 """
andrewonlabe6745342014-10-17 14:29:13 -04002224 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002225 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002226 if summary:
2227 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002228 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002229 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002230 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002231 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002232 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002233 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002234 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002235 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002236 else:
Jon Hallff566d52016-01-15 14:45:36 -08002237 intentType = ""
2238 # IF we want the summary of a specific intent type
2239 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002240 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002241 if intentType in jsonResult.keys():
2242 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002243 else:
Jon Hallff566d52016-01-15 14:45:36 -08002244 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002245 return handle
2246 else:
2247 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002248 except AssertionError:
2249 main.log.exception( "" )
2250 return None
2251 except ( TypeError, ValueError ):
2252 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002253 return None
2254 except pexpect.EOF:
2255 main.log.error( self.name + ": EOF exception found" )
2256 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002257 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002258 except Exception:
2259 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002260 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002261
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002262 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002263 """
You Wangfdcbfc42016-05-16 12:16:53 -07002264 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002265 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002266 list of intent IDs.
2267 Parameters:
2268 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002269 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002270 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002271 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002272 accepted.
2273 Returns a list of dictionaries if a list of intent IDs is accepted,
2274 and each dictionary maps 'id' to the Intent ID and 'state' to
2275 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002276 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002277
kelvin-onlab54400a92015-02-26 18:05:51 -08002278 try:
2279 state = "State is Undefined"
2280 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002281 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002282 else:
Jon Hallc6793552016-01-19 14:18:37 -08002283 rawJson = intentsJson
2284 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002285 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002286 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002287 if intentsId == intent[ 'id' ]:
2288 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002289 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002290 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002291 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002292 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002293 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002294 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002295 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002296 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002297 for intent in parsedIntentsJson:
2298 if intentsId[ i ] == intent[ 'id' ]:
2299 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002300 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002301 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002302 break
Jon Hallefbd9792015-03-05 16:11:36 -08002303 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002304 main.log.warn( "Could not find all intents in ONOS output" )
2305 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002306 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002307 else:
Jon Hall53158082017-05-18 11:17:00 -07002308 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002309 return None
Jon Hallc6793552016-01-19 14:18:37 -08002310 except ( TypeError, ValueError ):
2311 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002312 return None
2313 except pexpect.EOF:
2314 main.log.error( self.name + ": EOF exception found" )
2315 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002316 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002317 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002318 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002319 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002320
Jon Hallf539eb92017-05-22 17:18:42 -07002321 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002322 """
2323 Description:
2324 Check intents state
2325 Required:
2326 intentsId - List of intents ID to be checked
2327 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002328 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002329 state in the list.
2330 *NOTE: You can pass in a list of expected state,
2331 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002332 Return:
Jon Hall53158082017-05-18 11:17:00 -07002333 Returns main.TRUE only if all intent are the same as expected states,
2334 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002335 """
2336 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002337 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002338 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002339
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002340 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002341 intentsDict = []
2342 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002343 if isinstance( intentsId, types.StringType ) \
2344 and intent.get( 'id' ) == intentsId:
2345 intentsDict.append( intent )
2346 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002347 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002348 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002349
2350 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002351 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002352 "getting intents state" )
2353 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002354
2355 if isinstance( expectedState, types.StringType ):
2356 for intents in intentsDict:
2357 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002358 main.log.debug( self.name + " : Intent ID - " +
2359 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002360 " actual state = " +
2361 intents.get( 'state' )
2362 + " does not equal expected state = "
2363 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002364 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002365 elif isinstance( expectedState, types.ListType ):
2366 for intents in intentsDict:
2367 if not any( state == intents.get( 'state' ) for state in
2368 expectedState ):
2369 main.log.debug( self.name + " : Intent ID - " +
2370 intents.get( 'id' ) +
2371 " actual state = " +
2372 intents.get( 'state' ) +
2373 " does not equal expected states = "
2374 + str( expectedState ) )
2375 returnValue = main.FALSE
2376
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002377 if returnValue == main.TRUE:
2378 main.log.info( self.name + ": All " +
2379 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002380 " intents are in " + str( expectedState ) +
2381 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002382 return returnValue
2383 except TypeError:
2384 main.log.exception( self.name + ": Object not as expected" )
2385 return None
2386 except pexpect.EOF:
2387 main.log.error( self.name + ": EOF exception found" )
2388 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002389 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002390 except Exception:
2391 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002392 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002393
Jon Hallf539eb92017-05-22 17:18:42 -07002394 def compareBandwidthAllocations( self, expectedAllocations ):
2395 """
2396 Description:
2397 Compare the allocated bandwidth with the given allocations
2398 Required:
2399 expectedAllocations - The expected ONOS output of the allocations command
2400 Return:
2401 Returns main.TRUE only if all intent are the same as expected states,
2402 otherwise returns main.FALSE.
2403 """
2404 # FIXME: Convert these string comparisons to object comparisons
2405 try:
2406 returnValue = main.TRUE
2407 bandwidthFailed = False
2408 rawAlloc = self.allocations()
2409 expectedFormat = StringIO( expectedAllocations )
2410 ONOSOutput = StringIO( rawAlloc )
2411 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2412 str( expectedFormat ) ) )
2413
2414 for actual, expected in izip( ONOSOutput, expectedFormat ):
2415 actual = actual.rstrip()
2416 expected = expected.rstrip()
2417 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2418 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002419 marker1 = actual.find( 'allocated' )
2420 m1 = actual[ :marker1 ]
2421 marker2 = expected.find( 'allocated' )
2422 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002423 if m1 != m2:
2424 bandwidthFailed = True
2425 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2426 bandwidthFailed = True
2427 expectedFormat.close()
2428 ONOSOutput.close()
2429
2430 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002431 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002432 returnValue = main.FALSE
2433 return returnValue
2434 except TypeError:
2435 main.log.exception( self.name + ": Object not as expected" )
2436 return None
2437 except pexpect.EOF:
2438 main.log.error( self.name + ": EOF exception found" )
2439 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002440 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002441 except Exception:
2442 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002443 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002444
You Wang66518af2016-05-16 15:32:59 -07002445 def compareIntent( self, intentDict ):
2446 """
2447 Description:
2448 Compare the intent ids and states provided in the argument with all intents in ONOS
2449 Return:
2450 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2451 Arguments:
2452 intentDict: a dictionary which maps intent ids to intent states
2453 """
2454 try:
2455 intentsRaw = self.intents()
2456 intentsJson = json.loads( intentsRaw )
2457 intentDictONOS = {}
2458 for intent in intentsJson:
2459 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002460 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002461 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002462 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002463 str( len( intentDict ) ) + " expected and " +
2464 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002465 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002466 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002467 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002468 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2469 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002470 else:
2471 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2472 main.log.debug( self.name + ": intent ID - " + intentID +
2473 " expected state is " + intentDict[ intentID ] +
2474 " but actual state is " + intentDictONOS[ intentID ] )
2475 returnValue = main.FALSE
2476 intentDictONOS.pop( intentID )
2477 if len( intentDictONOS ) > 0:
2478 returnValue = main.FALSE
2479 for intentID in intentDictONOS.keys():
2480 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002481 if returnValue == main.TRUE:
2482 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2483 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002484 except KeyError:
2485 main.log.exception( self.name + ": KeyError exception found" )
2486 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002487 except ( TypeError, ValueError ):
2488 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002489 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002490 except pexpect.EOF:
2491 main.log.error( self.name + ": EOF exception found" )
2492 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002493 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002494 except Exception:
2495 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002496 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002497
YPZhang14a4aa92016-07-15 13:37:15 -07002498 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002499 """
2500 Description:
2501 Check the number of installed intents.
2502 Optional:
2503 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002504 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002505 Return:
2506 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2507 , otherwise, returns main.FALSE.
2508 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002509
GlennRCed771242016-01-13 17:02:47 -08002510 try:
2511 cmd = "intents -s -j"
2512
2513 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002514 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002515 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002516 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002517 response = json.loads( response )
2518
2519 # get total and installed number, see if they are match
2520 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002521 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002522 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2523 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002524 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002525 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2526 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002527 return main.FALSE
2528
Jon Hallc6793552016-01-19 14:18:37 -08002529 except ( TypeError, ValueError ):
2530 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002531 return None
2532 except pexpect.EOF:
2533 main.log.error( self.name + ": EOF exception found" )
2534 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002535 if noExit:
2536 return main.FALSE
2537 else:
Devin Lim44075962017-08-11 10:56:37 -07002538 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002539 except pexpect.TIMEOUT:
2540 main.log.error( self.name + ": ONOS timeout" )
2541 return None
GlennRCed771242016-01-13 17:02:47 -08002542 except Exception:
2543 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002544 if noExit:
2545 return main.FALSE
2546 else:
Devin Lim44075962017-08-11 10:56:37 -07002547 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002548
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002549 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002550 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002551 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002552 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002553 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002554 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002555 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002556 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002557 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002558 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002559 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002560 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002561 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002562 cmdStr += " -n"
2563 cmdStr += " " + state
2564 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002565 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002566 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002567 assert "Command not found:" not in handle, handle
2568 if re.search( "Error:", handle ):
2569 main.log.error( self.name + ": flows() response: " +
2570 str( handle ) )
2571 return handle
2572 except AssertionError:
2573 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002574 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002575 except TypeError:
2576 main.log.exception( self.name + ": Object not as expected" )
2577 return None
Jon Hallc6793552016-01-19 14:18:37 -08002578 except pexpect.TIMEOUT:
2579 main.log.error( self.name + ": ONOS timeout" )
2580 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002581 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002582 main.log.error( self.name + ": EOF exception found" )
2583 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002584 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002585 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002586 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002587 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002588
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002589 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002590 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002591 count = int( count ) if count else 0
2592 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002593
Jon Halle0f0b342017-04-18 11:43:47 -07002594 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002595 """
2596 Description:
GlennRCed771242016-01-13 17:02:47 -08002597 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002598 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2599 if the count of those states is 0, which means all current flows
2600 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002601 Optional:
GlennRCed771242016-01-13 17:02:47 -08002602 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002603 Return:
2604 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002605 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002606 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002607 """
2608 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002609 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002610 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002611 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002612 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002613 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002614 if rawFlows:
2615 # if we didn't get flows or flows function return None, we should return
2616 # main.Flase
2617 checkedStates.append( json.loads( rawFlows ) )
2618 else:
2619 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002620 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002621 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002622 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002623 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002624 except TypeError:
2625 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002626 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002627
GlennRCed771242016-01-13 17:02:47 -08002628 # We want to count PENDING_ADD if isPENDING is true
2629 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002630 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002631 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002632 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002633 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002634 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002635 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002636 except ( TypeError, ValueError ):
2637 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002638 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002639
YPZhang240842b2016-05-17 12:00:50 -07002640 except AssertionError:
2641 main.log.exception( "" )
2642 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002643 except pexpect.TIMEOUT:
2644 main.log.error( self.name + ": ONOS timeout" )
2645 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002646 except pexpect.EOF:
2647 main.log.error( self.name + ": EOF exception found" )
2648 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002649 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002650 except Exception:
2651 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002652 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002653
GlennRCed771242016-01-13 17:02:47 -08002654 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002655 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002656 """
andrewonlab87852b02014-11-19 18:44:19 -05002657 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002658 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002659 a specific point-to-point intent definition
2660 Required:
GlennRCed771242016-01-13 17:02:47 -08002661 * ingress: specify source dpid
2662 * egress: specify destination dpid
2663 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002664 Optional:
GlennRCed771242016-01-13 17:02:47 -08002665 * offset: the keyOffset is where the next batch of intents
2666 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002667 * noExit: If set to True, TestON will not exit if any error when issus command
2668 * getResponse: If set to True, function will return ONOS response.
2669
GlennRCed771242016-01-13 17:02:47 -08002670 Returns: If failed to push test intents, it will returen None,
2671 if successful, return true.
2672 Timeout expection will return None,
2673 TypeError will return false
2674 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002675 """
andrewonlab87852b02014-11-19 18:44:19 -05002676 try:
GlennRCed771242016-01-13 17:02:47 -08002677 if background:
2678 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002679 else:
GlennRCed771242016-01-13 17:02:47 -08002680 back = ""
2681 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002682 ingress,
2683 egress,
2684 batchSize,
2685 offset,
2686 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002687 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002688 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002689 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002690 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002691 if getResponse:
2692 return response
2693
GlennRCed771242016-01-13 17:02:47 -08002694 # TODO: We should handle if there is failure in installation
2695 return main.TRUE
2696
Jon Hallc6793552016-01-19 14:18:37 -08002697 except AssertionError:
2698 main.log.exception( "" )
2699 return None
GlennRCed771242016-01-13 17:02:47 -08002700 except pexpect.TIMEOUT:
2701 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002702 return None
andrewonlab87852b02014-11-19 18:44:19 -05002703 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002704 main.log.error( self.name + ": EOF exception found" )
2705 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002706 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002707 except TypeError:
2708 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002709 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002710 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002711 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002712 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002713
YPZhangebf9eb52016-05-12 15:20:24 -07002714 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002715 """
2716 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002717 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002718 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002719 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002720 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002721 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002722
YPZhangb5d3f832016-01-23 22:54:26 -08002723 try:
YPZhange3109a72016-02-02 11:25:37 -08002724 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002725 cmd = "flows -c added"
2726 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2727 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002728 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002729 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002730 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002731 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002732 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002733 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002734 return None
2735 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002736
You Wangd3cb2ce2016-05-16 14:01:24 -07002737 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002738 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002739 return None
2740 except pexpect.EOF:
2741 main.log.error( self.name + ": EOF exception found" )
2742 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002743 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002744 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002745 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002746 except pexpect.TIMEOUT:
2747 main.log.error( self.name + ": ONOS timeout" )
2748 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002749 except Exception:
2750 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002751 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002752 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002753 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002754
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002755 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002756 """
2757 Description:
2758 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002759 Optional:
2760 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002761 Return:
2762 The number of intents
2763 """
2764 try:
2765 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002766 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002767 if response is None:
2768 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002769 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002770 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002771 except ( TypeError, ValueError ):
2772 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002773 return None
2774 except pexpect.EOF:
2775 main.log.error( self.name + ": EOF exception found" )
2776 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002777 if noExit:
2778 return -1
2779 else:
Devin Lim44075962017-08-11 10:56:37 -07002780 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002781 except Exception:
2782 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002783 if noExit:
2784 return -1
2785 else:
Devin Lim44075962017-08-11 10:56:37 -07002786 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002787
kelvin-onlabd3b64892015-01-20 13:26:24 -08002788 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002789 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002790 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002791 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002792 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002793 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002794 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002795 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002796 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002797 cmdStr += " -j"
2798 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002799 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002800 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002801 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002802 except AssertionError:
2803 main.log.exception( "" )
2804 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002805 except TypeError:
2806 main.log.exception( self.name + ": Object not as expected" )
2807 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002808 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002809 main.log.error( self.name + ": EOF exception found" )
2810 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002811 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002812 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002813 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002814 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002815
kelvin-onlabd3b64892015-01-20 13:26:24 -08002816 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002817 """
2818 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002819 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002820 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002821 """
andrewonlab867212a2014-10-22 20:13:38 -04002822 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002823 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002824 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002825 cmdStr += " -j"
2826 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002827 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002828 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002829 if handle:
2830 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002831 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002832 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002833 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002834 else:
2835 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002836 except AssertionError:
2837 main.log.exception( "" )
2838 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002839 except TypeError:
2840 main.log.exception( self.name + ": Object not as expected" )
2841 return None
andrewonlab867212a2014-10-22 20:13:38 -04002842 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002843 main.log.error( self.name + ": EOF exception found" )
2844 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002845 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002846 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002847 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002848 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002849
kelvin8ec71442015-01-15 16:57:00 -08002850 # Wrapper functions ****************
2851 # Wrapper functions use existing driver
2852 # functions and extends their use case.
2853 # For example, we may use the output of
2854 # a normal driver function, and parse it
2855 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002856
kelvin-onlabd3b64892015-01-20 13:26:24 -08002857 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002858 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002859 Description:
2860 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002861 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002862 try:
kelvin8ec71442015-01-15 16:57:00 -08002863 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002864 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002865 if intentsStr is None:
2866 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002867 # Convert to a dictionary
2868 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002869 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002870 for intent in intents:
2871 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002872 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002873 except TypeError:
2874 main.log.exception( self.name + ": Object not as expected" )
2875 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002876 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()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002883
You Wang3c276252016-09-21 15:21:36 -07002884 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002885 """
2886 Determine the number of flow rules for the given device id that are
2887 in the added state
You Wang3c276252016-09-21 15:21:36 -07002888 Params:
2889 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002890 """
2891 try:
You Wang3c276252016-09-21 15:21:36 -07002892 if core:
2893 cmdStr = "flows any " + str( deviceId ) + " | " +\
2894 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2895 else:
2896 cmdStr = "flows any " + str( deviceId ) + " | " +\
2897 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002898 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002899 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002900 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002901 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002902 except AssertionError:
2903 main.log.exception( "" )
2904 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002905 except pexpect.EOF:
2906 main.log.error( self.name + ": EOF exception found" )
2907 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002908 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002909 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002910 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002911 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002912
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002913 def groupAddedCount( self, deviceId, core=False ):
2914 """
2915 Determine the number of group rules for the given device id that are
2916 in the added state
2917 Params:
2918 core: if True, only return the number of core groups added
2919 """
2920 try:
2921 if core:
2922 cmdStr = "groups any " + str( deviceId ) + " | " +\
2923 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2924 else:
2925 cmdStr = "groups any " + str( deviceId ) + " | " +\
2926 "grep 'state=ADDED' | wc -l"
2927 handle = self.sendline( cmdStr )
2928 assert handle is not None, "Error in sendline"
2929 assert "Command not found:" not in handle, handle
2930 return handle
2931 except AssertionError:
2932 main.log.exception( "" )
2933 return None
2934 except pexpect.EOF:
2935 main.log.error( self.name + ": EOF exception found" )
2936 main.log.error( self.name + ": " + self.handle.before )
2937 main.cleanAndExit()
2938 except Exception:
2939 main.log.exception( self.name + ": Uncaught exception!" )
2940 main.cleanAndExit()
2941
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002942 def addStaticRoute( self, subnet, intf):
2943 """
2944 Adds a static route to onos.
2945 Params:
2946 subnet: The subnet reaching through this route
2947 intf: The interface this route is reachable through
2948 """
2949 try:
2950 cmdStr = "route-add " + subnet + " " + intf
2951 handle = self.sendline( cmdStr )
2952 assert handle is not None, "Error in sendline"
2953 assert "Command not found:" not in handle, handle
2954 return handle
2955 except AssertionError:
2956 main.log.exception( "" )
2957 return None
2958 except pexpect.EOF:
2959 main.log.error( self.name + ": EOF exception found" )
2960 main.log.error( self.name + ": " + self.handle.before )
2961 main.cleanAndExit()
2962 except Exception:
2963 main.log.exception( self.name + ": Uncaught exception!" )
2964 main.cleanAndExit()
2965
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002966 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
2967 """
2968 Description:
2969 Check whether the number of groups for the given device id that
2970 are in ADDED state is bigger than minGroupCount.
2971 Required:
2972 * deviceId: device id to check the number of added group rules
2973 Optional:
2974 * minGroupCount: the number of groups to compare
2975 * core: if True, only check the number of core groups added
2976 * comparison: if 0, compare with greater than minFlowCount
2977 * if 1, compare with equal to minFlowCount
2978 Return:
2979 Returns the number of groups if it is bigger than minGroupCount,
2980 returns main.FALSE otherwise.
2981 """
2982 count = self.groupAddedCount( deviceId, core )
2983 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07002984 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002985 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
2986
You Wangc02f3be2018-05-18 12:14:23 -07002987 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002988 """
2989 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07002990 deviceId: Id of the device from which we retrieve groups
2991 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002992 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002993 try:
You Wangc02f3be2018-05-18 12:14:23 -07002994 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
2995 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002996 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 TypeError:
3003 main.log.exception( self.name + ": Object not as expected" )
3004 return None
3005 except pexpect.EOF:
3006 main.log.error( self.name + ": EOF exception found" )
3007 main.log.error( self.name + ": " + self.handle.before )
3008 main.cleanAndExit()
3009 except Exception:
3010 main.log.exception( self.name + ": Uncaught exception!" )
3011 main.cleanAndExit()
3012
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003013 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003014 """
3015 Description:
3016 Check whether the number of flow rules for the given device id that
3017 are in ADDED state is bigger than minFlowCount.
3018 Required:
3019 * deviceId: device id to check the number of added flow rules
3020 Optional:
3021 * minFlowCount: the number of flow rules to compare
3022 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003023 * comparison: if 0, compare with greater than minFlowCount
3024 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003025 Return:
3026 Returns the number of flow rules if it is bigger than minFlowCount,
3027 returns main.FALSE otherwise.
3028 """
3029 count = self.flowAddedCount( deviceId, core )
3030 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003031 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003032 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003033
kelvin-onlabd3b64892015-01-20 13:26:24 -08003034 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003035 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003036 Use 'devices' function to obtain list of all devices
3037 and parse the result to obtain a list of all device
3038 id's. Returns this list. Returns empty list if no
3039 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003040 List is ordered sequentially
3041
andrewonlab3e15ead2014-10-15 14:21:34 -04003042 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003043 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003044 the ids. By obtaining the list of device ids on the fly,
3045 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003046 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003047 try:
kelvin8ec71442015-01-15 16:57:00 -08003048 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003049 devicesStr = self.devices( jsonFormat=False )
3050 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003051
kelvin-onlabd3b64892015-01-20 13:26:24 -08003052 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003053 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003054 return idList
kelvin8ec71442015-01-15 16:57:00 -08003055
3056 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003057 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003058 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003059 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003060 # Split list further into arguments before and after string
3061 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003062 # append to idList
3063 for arg in tempList:
3064 idList.append( arg.split( "id=" )[ 1 ] )
3065 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003066
Jon Halld4d4b372015-01-28 16:02:41 -08003067 except TypeError:
3068 main.log.exception( self.name + ": Object not as expected" )
3069 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003070 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003071 main.log.error( self.name + ": EOF exception found" )
3072 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003073 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003074 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003075 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003076 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003077
kelvin-onlabd3b64892015-01-20 13:26:24 -08003078 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003079 """
andrewonlab7c211572014-10-15 16:45:20 -04003080 Uses 'nodes' function to obtain list of all nodes
3081 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003082 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003083 Returns:
3084 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003085 """
andrewonlab7c211572014-10-15 16:45:20 -04003086 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003087 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003088 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003089 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003090 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003091 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003092 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003093 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003094 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003095 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003096 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003097 except ( TypeError, ValueError ):
3098 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003099 return None
andrewonlab7c211572014-10-15 16:45:20 -04003100 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003101 main.log.error( self.name + ": EOF exception found" )
3102 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003103 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003104 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003105 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003106 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003107
kelvin-onlabd3b64892015-01-20 13:26:24 -08003108 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003109 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003110 Return the first device from the devices api whose 'id' contains 'dpid'
3111 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003112 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003113 try:
kelvin8ec71442015-01-15 16:57:00 -08003114 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003115 return None
3116 else:
kelvin8ec71442015-01-15 16:57:00 -08003117 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003118 rawDevices = self.devices()
3119 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003120 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003121 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003122 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3123 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003124 return device
3125 return None
Jon Hallc6793552016-01-19 14:18:37 -08003126 except ( TypeError, ValueError ):
3127 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003128 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003129 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003130 main.log.error( self.name + ": EOF exception found" )
3131 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003132 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003133 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003134 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003135 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003136
You Wang24139872016-05-03 11:48:47 -07003137 def getTopology( self, topologyOutput ):
3138 """
3139 Definition:
3140 Loads a json topology output
3141 Return:
3142 topology = current ONOS topology
3143 """
3144 import json
3145 try:
3146 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003147 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003148 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003149 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003150 except ( TypeError, ValueError ):
3151 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3152 return None
You Wang24139872016-05-03 11:48:47 -07003153 except pexpect.EOF:
3154 main.log.error( self.name + ": EOF exception found" )
3155 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003156 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003157 except Exception:
3158 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003159 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003160
Pier6a0c4de2018-03-18 16:01:30 -07003161 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003162 """
Jon Hallefbd9792015-03-05 16:11:36 -08003163 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003164 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003165 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003166
Flavio Castro82ee2f62016-06-07 15:04:12 -07003167 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003168 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003169 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003170 logLevel = level to log to.
3171 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003172
Jon Hallefbd9792015-03-05 16:11:36 -08003173 Returns: main.TRUE if the number of switches and links are correct,
3174 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003175 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003176 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003177 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003178 try:
You Wang13310252016-07-31 10:56:14 -07003179 summary = self.summary()
3180 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003181 except ( TypeError, ValueError ):
3182 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3183 return main.ERROR
3184 try:
3185 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003186 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003187 return main.ERROR
3188 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003189 # Is the number of switches is what we expected
3190 devices = topology.get( 'devices', False )
3191 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003192 nodes = summary.get( 'nodes', False )
3193 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003194 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003195 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003196 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003197 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003198 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3199 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003200 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003201 output = output + "The number of links and switches match "\
3202 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003203 result = main.TRUE
3204 else:
You Wang24139872016-05-03 11:48:47 -07003205 output = output + \
3206 "The number of links and switches does not match " + \
3207 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003208 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003209 output = output + "\n ONOS sees %i devices" % int( devices )
3210 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003211 if int( numolink ) > 0:
3212 output = output + "and %i links " % int( links )
3213 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003214 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003215 output = output + "and %i controllers " % int( nodes )
3216 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003217 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003218 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003219 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003220 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003221 else:
You Wang24139872016-05-03 11:48:47 -07003222 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003223 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003224 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003225 main.log.error( self.name + ": EOF exception found" )
3226 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003227 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003228 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003229 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003230 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003231
kelvin-onlabd3b64892015-01-20 13:26:24 -08003232 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003233 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003234 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003235 deviceId must be the id of a device as seen in the onos devices command
3236 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003237 role must be either master, standby, or none
3238
Jon Halle3f39ff2015-01-13 11:50:53 -08003239 Returns:
3240 main.TRUE or main.FALSE based on argument verification and
3241 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003242 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003243 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003244 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003245 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003246 cmdStr = "device-role " +\
3247 str( deviceId ) + " " +\
3248 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003249 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003250 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003251 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003252 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003253 if re.search( "Error", handle ):
3254 # end color output to escape any colours
3255 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003256 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003257 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003258 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003259 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003260 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003261 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003262 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003263 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003264 except AssertionError:
3265 main.log.exception( "" )
3266 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003267 except TypeError:
3268 main.log.exception( self.name + ": Object not as expected" )
3269 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003270 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003271 main.log.error( self.name + ": EOF exception found" )
3272 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003273 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003274 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003275 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003276 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003277
kelvin-onlabd3b64892015-01-20 13:26:24 -08003278 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003279 """
Jon Hall0dd09952018-04-19 09:59:11 -07003280 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003281 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003282 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003283 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003284 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003285 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003286 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003287 cmdStr += " -j"
3288 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003289 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003290 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003291 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003292 except AssertionError:
3293 main.log.exception( "" )
3294 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003295 except TypeError:
3296 main.log.exception( self.name + ": Object not as expected" )
3297 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003298 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003299 main.log.error( self.name + ": EOF exception found" )
3300 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003301 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003302 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003303 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003304 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003305
kelvin-onlabd3b64892015-01-20 13:26:24 -08003306 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003307 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003308 CLI command to get the current leader for the Election test application
3309 NOTE: Requires installation of the onos-app-election feature
3310 Returns: Node IP of the leader if one exists
3311 None if none exists
3312 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003313 """
Jon Hall94fd0472014-12-08 11:52:42 -08003314 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003315 cmdStr = "election-test-leader"
3316 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003317 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003318 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003319 # Leader
3320 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003321 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003322 nodeSearch = re.search( leaderPattern, response )
3323 if nodeSearch:
3324 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003325 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003326 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003327 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003328 # no leader
3329 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003330 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003331 nullSearch = re.search( nullPattern, response )
3332 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003333 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003334 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003335 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003336 # error
Jon Hall0e240372018-05-02 11:21:57 -07003337 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003338 ": " + "unexpected response" )
3339 main.log.error( repr( response ) )
3340 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003341 except AssertionError:
3342 main.log.exception( "" )
3343 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003344 except TypeError:
3345 main.log.exception( self.name + ": Object not as expected" )
3346 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003347 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003348 main.log.error( self.name + ": EOF exception found" )
3349 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003350 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003351 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003352 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003353 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003354
kelvin-onlabd3b64892015-01-20 13:26:24 -08003355 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003356 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003357 CLI command to run for leadership of the Election test application.
3358 NOTE: Requires installation of the onos-app-election feature
3359 Returns: Main.TRUE on success
3360 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003361 """
Jon Hall94fd0472014-12-08 11:52:42 -08003362 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003363 cmdStr = "election-test-run"
3364 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003365 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003366 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003367 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003368 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003369 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003370 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003371 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003372 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003373 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003374 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003375 # error
Jon Hall0e240372018-05-02 11:21:57 -07003376 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003377 ": " + "unexpected response" )
3378 main.log.error( repr( response ) )
3379 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003380 except AssertionError:
3381 main.log.exception( "" )
3382 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003383 except TypeError:
3384 main.log.exception( self.name + ": Object not as expected" )
3385 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003386 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003387 main.log.error( self.name + ": EOF exception found" )
3388 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003389 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003390 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003391 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003392 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003393
kelvin-onlabd3b64892015-01-20 13:26:24 -08003394 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003395 """
Jon Hall94fd0472014-12-08 11:52:42 -08003396 * CLI command to withdraw the local node from leadership election for
3397 * the Election test application.
3398 #NOTE: Requires installation of the onos-app-election feature
3399 Returns: Main.TRUE on success
3400 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003401 """
Jon Hall94fd0472014-12-08 11:52:42 -08003402 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003403 cmdStr = "election-test-withdraw"
3404 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003405 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003406 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003407 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003408 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003409 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003410 if re.search( successPattern, response ):
3411 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003412 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003413 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003414 # error
Jon Hall0e240372018-05-02 11:21:57 -07003415 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003416 self.name + ": " + "unexpected response" )
3417 main.log.error( repr( response ) )
3418 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003419 except AssertionError:
3420 main.log.exception( "" )
3421 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003422 except TypeError:
3423 main.log.exception( self.name + ": Object not as expected" )
3424 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003425 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003426 main.log.error( self.name + ": EOF exception found" )
3427 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003428 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003429 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003430 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003431 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003432
kelvin8ec71442015-01-15 16:57:00 -08003433 def getDevicePortsEnabledCount( self, dpid ):
3434 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003435 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003436 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003437 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003438 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003439 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3440 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003441 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003442 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003443 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003444 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003445 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003446 return output
Jon Hallc6793552016-01-19 14:18:37 -08003447 except AssertionError:
3448 main.log.exception( "" )
3449 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003450 except TypeError:
3451 main.log.exception( self.name + ": Object not as expected" )
3452 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003453 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003454 main.log.error( self.name + ": EOF exception found" )
3455 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003456 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003457 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003458 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003459 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003460
kelvin8ec71442015-01-15 16:57:00 -08003461 def getDeviceLinksActiveCount( self, dpid ):
3462 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003463 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003464 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003465 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003466 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003467 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3468 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003469 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003470 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003471 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003472 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003473 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003474 return output
Jon Hallc6793552016-01-19 14:18:37 -08003475 except AssertionError:
3476 main.log.exception( "" )
3477 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003478 except TypeError:
3479 main.log.exception( self.name + ": Object not as expected" )
3480 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003481 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003482 main.log.error( self.name + ": EOF exception found" )
3483 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003484 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003485 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003486 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003487 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003488
kelvin8ec71442015-01-15 16:57:00 -08003489 def getAllIntentIds( self ):
3490 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003491 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003492 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003493 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003494 cmdStr = "onos:intents | grep id="
3495 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003496 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003497 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003498 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003499 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003500 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003501 return output
Jon Hallc6793552016-01-19 14:18:37 -08003502 except AssertionError:
3503 main.log.exception( "" )
3504 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003505 except TypeError:
3506 main.log.exception( self.name + ": Object not as expected" )
3507 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003508 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003509 main.log.error( self.name + ": EOF exception found" )
3510 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003511 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003512 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003513 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003514 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003515
Jon Hall73509952015-02-24 16:42:56 -08003516 def intentSummary( self ):
3517 """
Jon Hallefbd9792015-03-05 16:11:36 -08003518 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003519 """
3520 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003521 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003522 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003523 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003524 states.append( intent.get( 'state', None ) )
3525 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003526 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003527 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003528 except ( TypeError, ValueError ):
3529 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003530 return None
3531 except pexpect.EOF:
3532 main.log.error( self.name + ": EOF exception found" )
3533 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003534 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003535 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003536 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003537 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003538
Jon Hall61282e32015-03-19 11:34:11 -07003539 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003540 """
3541 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003542 Optional argument:
3543 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003544 """
Jon Hall63604932015-02-26 17:09:50 -08003545 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003546 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003547 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003548 cmdStr += " -j"
3549 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003550 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003551 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003552 return output
Jon Hallc6793552016-01-19 14:18:37 -08003553 except AssertionError:
3554 main.log.exception( "" )
3555 return None
Jon Hall63604932015-02-26 17:09:50 -08003556 except TypeError:
3557 main.log.exception( self.name + ": Object not as expected" )
3558 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003559 except pexpect.EOF:
3560 main.log.error( self.name + ": EOF exception found" )
3561 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003562 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003563 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003564 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003565 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003566
acsmarsa4a4d1e2015-07-10 16:01:24 -07003567 def leaderCandidates( self, jsonFormat=True ):
3568 """
3569 Returns the output of the leaders -c command.
3570 Optional argument:
3571 * jsonFormat - boolean indicating if you want output in json
3572 """
3573 try:
3574 cmdStr = "onos:leaders -c"
3575 if jsonFormat:
3576 cmdStr += " -j"
3577 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003578 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003579 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003580 return output
Jon Hallc6793552016-01-19 14:18:37 -08003581 except AssertionError:
3582 main.log.exception( "" )
3583 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003584 except TypeError:
3585 main.log.exception( self.name + ": Object not as expected" )
3586 return None
3587 except pexpect.EOF:
3588 main.log.error( self.name + ": EOF exception found" )
3589 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003590 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003591 except Exception:
3592 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003593 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003594
Jon Hallc6793552016-01-19 14:18:37 -08003595 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003596 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003597 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003598 topic parameter and an empty list if the topic doesn't exist
3599 If no leader is elected leader in the returned list will be "none"
3600 Returns None if there is a type error processing the json object
3601 """
3602 try:
Jon Hall6e709752016-02-01 13:38:46 -08003603 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003604 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003605 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003606 assert "Command not found:" not in rawOutput, rawOutput
3607 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003608 results = []
3609 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003610 if dict[ "topic" ] == topic:
3611 leader = dict[ "leader" ]
3612 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003613 results.append( leader )
3614 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003615 return results
Jon Hallc6793552016-01-19 14:18:37 -08003616 except AssertionError:
3617 main.log.exception( "" )
3618 return None
3619 except ( TypeError, ValueError ):
3620 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003621 return None
3622 except pexpect.EOF:
3623 main.log.error( self.name + ": EOF exception found" )
3624 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003625 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003626 except Exception:
3627 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003628 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003629
Jon Hall61282e32015-03-19 11:34:11 -07003630 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003631 """
3632 Returns the output of the intent Pending map.
3633 """
Jon Hall63604932015-02-26 17:09:50 -08003634 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003635 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003636 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003637 cmdStr += " -j"
3638 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003639 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003640 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003641 return output
Jon Hallc6793552016-01-19 14:18:37 -08003642 except AssertionError:
3643 main.log.exception( "" )
3644 return None
Jon Hall63604932015-02-26 17:09:50 -08003645 except TypeError:
3646 main.log.exception( self.name + ": Object not as expected" )
3647 return None
3648 except pexpect.EOF:
3649 main.log.error( self.name + ": EOF exception found" )
3650 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003651 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003652 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003653 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003654 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003655
Jon Hall2c8959e2016-12-16 12:17:34 -08003656 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003657 """
3658 Returns the output of the raft partitions command for ONOS.
3659 """
Jon Hall61282e32015-03-19 11:34:11 -07003660 # Sample JSON
3661 # {
3662 # "leader": "tcp://10.128.30.11:7238",
3663 # "members": [
3664 # "tcp://10.128.30.11:7238",
3665 # "tcp://10.128.30.17:7238",
3666 # "tcp://10.128.30.13:7238",
3667 # ],
3668 # "name": "p1",
3669 # "term": 3
3670 # },
Jon Hall63604932015-02-26 17:09:50 -08003671 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003672 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003673 if candidates:
3674 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003675 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003676 cmdStr += " -j"
3677 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003678 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003679 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003680 return output
Jon Hallc6793552016-01-19 14:18:37 -08003681 except AssertionError:
3682 main.log.exception( "" )
3683 return None
Jon Hall63604932015-02-26 17:09:50 -08003684 except TypeError:
3685 main.log.exception( self.name + ": Object not as expected" )
3686 return None
3687 except pexpect.EOF:
3688 main.log.error( self.name + ": EOF exception found" )
3689 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003690 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003691 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003692 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003693 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003694
Jon Halle9f909e2016-09-23 10:43:12 -07003695 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003696 """
3697 Returns the output of the apps command for ONOS. This command lists
3698 information about installed ONOS applications
3699 """
3700 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003701 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003702 # "description":"ONOS OpenFlow protocol southbound providers",
3703 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003704 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003705 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003706 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003707 if summary:
3708 cmdStr += " -s"
3709 if active:
3710 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003711 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003712 cmdStr += " -j"
3713 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003714 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003715 assert "Command not found:" not in output, output
3716 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003717 return output
Jon Hallbe379602015-03-24 13:39:32 -07003718 # FIXME: look at specific exceptions/Errors
3719 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003720 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003721 return None
3722 except TypeError:
3723 main.log.exception( self.name + ": Object not as expected" )
3724 return None
3725 except pexpect.EOF:
3726 main.log.error( self.name + ": EOF exception found" )
3727 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003728 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003729 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003730 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003731 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003732
You Wangcdc51fe2018-08-12 17:14:56 -07003733 def appStatus( self, appName ):
Jon Hall146f1522015-03-24 15:33:24 -07003734 """
3735 Uses the onos:apps cli command to return the status of an application.
3736 Returns:
3737 "ACTIVE" - If app is installed and activated
3738 "INSTALLED" - If app is installed and deactivated
3739 "UNINSTALLED" - If app is not installed
3740 None - on error
3741 """
Jon Hall146f1522015-03-24 15:33:24 -07003742 try:
3743 if not isinstance( appName, types.StringType ):
3744 main.log.error( self.name + ".appStatus(): appName must be" +
3745 " a string" )
3746 return None
3747 output = self.apps( jsonFormat=True )
3748 appsJson = json.loads( output )
3749 state = None
3750 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003751 if appName == app.get( 'name' ):
3752 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003753 break
3754 if state == "ACTIVE" or state == "INSTALLED":
3755 return state
3756 elif state is None:
You Wang0d9f2c02018-08-10 14:56:32 -07003757 main.log.warn( "{} app not found".format( appName ) )
Jon Hall146f1522015-03-24 15:33:24 -07003758 return "UNINSTALLED"
3759 elif state:
3760 main.log.error( "Unexpected state from 'onos:apps': " +
3761 str( state ) )
3762 return state
Jon Hallc6793552016-01-19 14:18:37 -08003763 except ( TypeError, ValueError ):
3764 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003765 return None
3766 except pexpect.EOF:
3767 main.log.error( self.name + ": EOF exception found" )
3768 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003769 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003770 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003771 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003772 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003773
Jon Hallbe379602015-03-24 13:39:32 -07003774 def app( self, appName, option ):
3775 """
3776 Interacts with the app command for ONOS. This command manages
3777 application inventory.
3778 """
Jon Hallbe379602015-03-24 13:39:32 -07003779 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003780 # Validate argument types
3781 valid = True
3782 if not isinstance( appName, types.StringType ):
3783 main.log.error( self.name + ".app(): appName must be a " +
3784 "string" )
3785 valid = False
3786 if not isinstance( option, types.StringType ):
3787 main.log.error( self.name + ".app(): option must be a string" )
3788 valid = False
3789 if not valid:
3790 return main.FALSE
3791 # Validate Option
3792 option = option.lower()
3793 # NOTE: Install may become a valid option
3794 if option == "activate":
3795 pass
3796 elif option == "deactivate":
3797 pass
3798 elif option == "uninstall":
3799 pass
3800 else:
3801 # Invalid option
3802 main.log.error( "The ONOS app command argument only takes " +
3803 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003804 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003805 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003806 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003807 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003808 assert output is not None, "Error in sendline"
3809 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003810 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003811 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003812 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003813 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003814 elif "No such application" in output:
3815 main.log.error( "The application '" + appName +
3816 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003817 return main.FALSE
3818 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003819 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003820 str( output ) )
3821 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003822 elif "Unsupported command:" in output:
3823 main.log.error( "Incorrect command given to 'app': " +
3824 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003825 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003826 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003827 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003828 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003829 except AssertionError:
3830 main.log.exception( self.name + ": AssertionError exception found" )
3831 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003832 except TypeError:
3833 main.log.exception( self.name + ": Object not as expected" )
3834 return main.ERROR
3835 except pexpect.EOF:
3836 main.log.error( self.name + ": EOF exception found" )
3837 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003838 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003839 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003840 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003841 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003842
Jon Hallbd16b922015-03-26 17:53:15 -07003843 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003844 """
3845 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003846 appName is the hierarchical app name, not the feature name
3847 If check is True, method will check the status of the app after the
3848 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003849 Returns main.TRUE if the command was successfully sent
3850 main.FALSE if the cli responded with an error or given
3851 incorrect input
3852 """
3853 try:
3854 if not isinstance( appName, types.StringType ):
3855 main.log.error( self.name + ".activateApp(): appName must be" +
3856 " a string" )
3857 return main.FALSE
3858 status = self.appStatus( appName )
3859 if status == "INSTALLED":
3860 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003861 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003862 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003863 status = self.appStatus( appName )
3864 if status == "ACTIVE":
3865 return main.TRUE
3866 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003867 main.log.debug( "The state of application " +
3868 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003869 time.sleep( 1 )
3870 return main.FALSE
3871 else: # not 'check' or command didn't succeed
3872 return response
Jon Hall146f1522015-03-24 15:33:24 -07003873 elif status == "ACTIVE":
3874 return main.TRUE
3875 elif status == "UNINSTALLED":
3876 main.log.error( self.name + ": Tried to activate the " +
3877 "application '" + appName + "' which is not " +
3878 "installed." )
3879 else:
3880 main.log.error( "Unexpected return value from appStatus: " +
3881 str( status ) )
3882 return main.ERROR
3883 except TypeError:
3884 main.log.exception( self.name + ": Object not as expected" )
3885 return main.ERROR
3886 except pexpect.EOF:
3887 main.log.error( self.name + ": EOF exception found" )
3888 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003889 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003890 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003891 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003892 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003893
Jon Hallbd16b922015-03-26 17:53:15 -07003894 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003895 """
3896 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003897 appName is the hierarchical app name, not the feature name
3898 If check is True, method will check the status of the app after the
3899 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003900 Returns main.TRUE if the command was successfully sent
3901 main.FALSE if the cli responded with an error or given
3902 incorrect input
3903 """
3904 try:
3905 if not isinstance( appName, types.StringType ):
3906 main.log.error( self.name + ".deactivateApp(): appName must " +
3907 "be a string" )
3908 return main.FALSE
3909 status = self.appStatus( appName )
3910 if status == "INSTALLED":
3911 return main.TRUE
3912 elif status == "ACTIVE":
3913 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003914 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003915 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003916 status = self.appStatus( appName )
3917 if status == "INSTALLED":
3918 return main.TRUE
3919 else:
3920 time.sleep( 1 )
3921 return main.FALSE
3922 else: # not check or command didn't succeed
3923 return response
Jon Hall146f1522015-03-24 15:33:24 -07003924 elif status == "UNINSTALLED":
3925 main.log.warn( self.name + ": Tried to deactivate the " +
3926 "application '" + appName + "' which is not " +
3927 "installed." )
3928 return main.TRUE
3929 else:
3930 main.log.error( "Unexpected return value from appStatus: " +
3931 str( status ) )
3932 return main.ERROR
3933 except TypeError:
3934 main.log.exception( self.name + ": Object not as expected" )
3935 return main.ERROR
3936 except pexpect.EOF:
3937 main.log.error( self.name + ": EOF exception found" )
3938 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003939 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003940 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003941 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003942 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003943
Jon Hallbd16b922015-03-26 17:53:15 -07003944 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003945 """
3946 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003947 appName is the hierarchical app name, not the feature name
3948 If check is True, method will check the status of the app after the
3949 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003950 Returns main.TRUE if the command was successfully sent
3951 main.FALSE if the cli responded with an error or given
3952 incorrect input
3953 """
3954 # TODO: check with Thomas about the state machine for apps
3955 try:
3956 if not isinstance( appName, types.StringType ):
3957 main.log.error( self.name + ".uninstallApp(): appName must " +
3958 "be a string" )
3959 return main.FALSE
3960 status = self.appStatus( appName )
3961 if status == "INSTALLED":
3962 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003963 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003964 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003965 status = self.appStatus( appName )
3966 if status == "UNINSTALLED":
3967 return main.TRUE
3968 else:
3969 time.sleep( 1 )
3970 return main.FALSE
3971 else: # not check or command didn't succeed
3972 return response
Jon Hall146f1522015-03-24 15:33:24 -07003973 elif status == "ACTIVE":
3974 main.log.warn( self.name + ": Tried to uninstall the " +
3975 "application '" + appName + "' which is " +
3976 "currently active." )
3977 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003978 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003979 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003980 status = self.appStatus( appName )
3981 if status == "UNINSTALLED":
3982 return main.TRUE
3983 else:
3984 time.sleep( 1 )
3985 return main.FALSE
3986 else: # not check or command didn't succeed
3987 return response
Jon Hall146f1522015-03-24 15:33:24 -07003988 elif status == "UNINSTALLED":
3989 return main.TRUE
3990 else:
3991 main.log.error( "Unexpected return value from appStatus: " +
3992 str( status ) )
3993 return main.ERROR
3994 except TypeError:
3995 main.log.exception( self.name + ": Object not as expected" )
3996 return main.ERROR
3997 except pexpect.EOF:
3998 main.log.error( self.name + ": EOF exception found" )
3999 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004000 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004001 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07004002 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004003 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004004
4005 def appIDs( self, jsonFormat=True ):
4006 """
4007 Show the mappings between app id and app names given by the 'app-ids'
4008 cli command
4009 """
4010 try:
4011 cmdStr = "app-ids"
4012 if jsonFormat:
4013 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004014 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004015 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004016 assert "Command not found:" not in output, output
4017 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004018 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004019 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004020 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004021 return None
4022 except TypeError:
4023 main.log.exception( self.name + ": Object not as expected" )
4024 return None
4025 except pexpect.EOF:
4026 main.log.error( self.name + ": EOF exception found" )
4027 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004028 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004029 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004030 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004031 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004032
4033 def appToIDCheck( self ):
4034 """
4035 This method will check that each application's ID listed in 'apps' is
4036 the same as the ID listed in 'app-ids'. The check will also check that
4037 there are no duplicate IDs issued. Note that an app ID should be
4038 a globaly unique numerical identifier for app/app-like features. Once
4039 an ID is registered, the ID is never freed up so that if an app is
4040 reinstalled it will have the same ID.
4041
4042 Returns: main.TRUE if the check passes and
4043 main.FALSE if the check fails or
4044 main.ERROR if there is some error in processing the test
4045 """
4046 try:
Jon Hall0e240372018-05-02 11:21:57 -07004047 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004048 rawJson = self.appIDs( jsonFormat=True )
4049 if rawJson:
4050 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004051 else:
Jon Hall0e240372018-05-02 11:21:57 -07004052 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4053 return main.FALSE
4054
4055 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004056 rawJson = self.apps( jsonFormat=True )
4057 if rawJson:
4058 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004059 else:
Jon Hallc6793552016-01-19 14:18:37 -08004060 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004061 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004062
Jon Hallbd16b922015-03-26 17:53:15 -07004063 result = main.TRUE
4064 for app in apps:
4065 appID = app.get( 'id' )
4066 if appID is None:
4067 main.log.error( "Error parsing app: " + str( app ) )
4068 result = main.FALSE
4069 appName = app.get( 'name' )
4070 if appName is None:
4071 main.log.error( "Error parsing app: " + str( app ) )
4072 result = main.FALSE
4073 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004074 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004075 if not current: # if ids doesn't have this id
4076 result = main.FALSE
4077 main.log.error( "'app-ids' does not have the ID for " +
4078 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004079 main.log.debug( "apps command returned: " + str( app ) +
4080 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004081 elif len( current ) > 1:
4082 # there is more than one app with this ID
4083 result = main.FALSE
4084 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004085 elif not current[ 0 ][ 'name' ] == appName:
4086 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004087 result = main.FALSE
4088 main.log.error( "'app-ids' has " + str( currentName ) +
4089 " registered under id:" + str( appID ) +
4090 " but 'apps' has " + str( appName ) )
4091 else:
4092 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004093
Jon Hallbd16b922015-03-26 17:53:15 -07004094 # now make sure that app-ids has no duplicates
4095 idsList = []
4096 namesList = []
4097 for item in ids:
4098 idsList.append( item[ 'id' ] )
4099 namesList.append( item[ 'name' ] )
4100 if len( idsList ) != len( set( idsList ) ) or\
4101 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004102 main.log.error( "'app-ids' has some duplicate entries: \n"
4103 + json.dumps( ids,
4104 sort_keys=True,
4105 indent=4,
4106 separators=( ',', ': ' ) ) )
4107 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004108 return result
Jon Hallc6793552016-01-19 14:18:37 -08004109 except ( TypeError, ValueError ):
4110 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004111 return main.ERROR
4112 except pexpect.EOF:
4113 main.log.error( self.name + ": EOF exception found" )
4114 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004115 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004116 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004117 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004118 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004119
Jon Hallfb760a02015-04-13 15:35:03 -07004120 def getCfg( self, component=None, propName=None, short=False,
4121 jsonFormat=True ):
4122 """
4123 Get configuration settings from onos cli
4124 Optional arguments:
4125 component - Optionally only list configurations for a specific
4126 component. If None, all components with configurations
4127 are displayed. Case Sensitive string.
4128 propName - If component is specified, propName option will show
4129 only this specific configuration from that component.
4130 Case Sensitive string.
4131 jsonFormat - Returns output as json. Note that this will override
4132 the short option
4133 short - Short, less verbose, version of configurations.
4134 This is overridden by the json option
4135 returns:
4136 Output from cli as a string or None on error
4137 """
4138 try:
4139 baseStr = "cfg"
4140 cmdStr = " get"
4141 componentStr = ""
4142 if component:
4143 componentStr += " " + component
4144 if propName:
4145 componentStr += " " + propName
4146 if jsonFormat:
4147 baseStr += " -j"
4148 elif short:
4149 baseStr += " -s"
4150 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004151 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004152 assert "Command not found:" not in output, output
4153 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004154 return output
4155 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004156 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004157 return None
4158 except TypeError:
4159 main.log.exception( self.name + ": Object not as expected" )
4160 return None
4161 except pexpect.EOF:
4162 main.log.error( self.name + ": EOF exception found" )
4163 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004164 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004165 except Exception:
4166 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004167 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004168
4169 def setCfg( self, component, propName, value=None, check=True ):
4170 """
4171 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004172 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004173 component - The case sensitive name of the component whose
4174 property is to be set
4175 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004176 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004177 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004178 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004179 check - Boolean, Check whether the option was successfully set this
4180 only applies when a value is given.
4181 returns:
4182 main.TRUE on success or main.FALSE on failure. If check is False,
4183 will return main.TRUE unless there is an error
4184 """
4185 try:
4186 baseStr = "cfg"
4187 cmdStr = " set " + str( component ) + " " + str( propName )
4188 if value is not None:
4189 cmdStr += " " + str( value )
4190 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004191 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004192 assert "Command not found:" not in output, output
4193 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004194 if value and check:
4195 results = self.getCfg( component=str( component ),
4196 propName=str( propName ),
4197 jsonFormat=True )
4198 # Check if current value is what we just set
4199 try:
4200 jsonOutput = json.loads( results )
4201 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004202 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004203 main.log.exception( "Error parsing cfg output" )
4204 main.log.error( "output:" + repr( results ) )
4205 return main.FALSE
4206 if current == str( value ):
4207 return main.TRUE
4208 return main.FALSE
4209 return main.TRUE
4210 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004211 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004212 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004213 except ( TypeError, ValueError ):
4214 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004215 return main.FALSE
4216 except pexpect.EOF:
4217 main.log.error( self.name + ": EOF exception found" )
4218 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004219 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004220 except Exception:
4221 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004222 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004223
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004224 def distPrimitivesSend( self, cmd ):
4225 """
4226 Function to handle sending cli commands for the distributed primitives test app
4227
4228 This command will catch some exceptions and retry the command on some
4229 specific store exceptions.
4230
4231 Required arguments:
4232 cmd - The command to send to the cli
4233 returns:
4234 string containing the cli output
4235 None on Error
4236 """
4237 try:
4238 output = self.sendline( cmd )
4239 try:
4240 assert output is not None, "Error in sendline"
4241 # TODO: Maybe make this less hardcoded
4242 # ConsistentMap Exceptions
4243 assert "org.onosproject.store.service" not in output
4244 # Node not leader
4245 assert "java.lang.IllegalStateException" not in output
4246 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004247 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004248 "command: " + str( output ) )
4249 retryTime = 30 # Conservative time, given by Madan
4250 main.log.info( "Waiting " + str( retryTime ) +
4251 "seconds before retrying." )
4252 time.sleep( retryTime ) # Due to change in mastership
4253 output = self.sendline( cmd )
4254 assert output is not None, "Error in sendline"
4255 assert "Command not found:" not in output, output
4256 assert "Error executing command" not in output, output
4257 main.log.info( self.name + ": " + output )
4258 return output
4259 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004260 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004261 return None
4262 except TypeError:
4263 main.log.exception( self.name + ": Object not as expected" )
4264 return None
4265 except pexpect.EOF:
4266 main.log.error( self.name + ": EOF exception found" )
4267 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004268 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004269 except Exception:
4270 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004271 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004272
Jon Hall390696c2015-05-05 17:13:41 -07004273 def setTestAdd( self, setName, values ):
4274 """
4275 CLI command to add elements to a distributed set.
4276 Arguments:
4277 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004278 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004279 Example usages:
4280 setTestAdd( "set1", "a b c" )
4281 setTestAdd( "set2", "1" )
4282 returns:
4283 main.TRUE on success OR
4284 main.FALSE if elements were already in the set OR
4285 main.ERROR on error
4286 """
4287 try:
4288 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004289 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004290 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4291 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004292 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004293 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004294 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004295 return main.FALSE
4296 else:
4297 main.log.error( self.name + ": setTestAdd did not" +
4298 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004299 main.log.debug( self.name + " actual: " + repr( output ) )
4300 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004301 except TypeError:
4302 main.log.exception( self.name + ": Object not as expected" )
4303 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004304 except Exception:
4305 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004306 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004307
4308 def setTestRemove( self, setName, values, clear=False, retain=False ):
4309 """
4310 CLI command to remove elements from a distributed set.
4311 Required arguments:
4312 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004313 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004314 Optional arguments:
4315 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004316 retain - Retain only the given values. (intersection of the
4317 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004318 returns:
4319 main.TRUE on success OR
4320 main.FALSE if the set was not changed OR
4321 main.ERROR on error
4322 """
4323 try:
4324 cmdStr = "set-test-remove "
4325 if clear:
4326 cmdStr += "-c " + str( setName )
4327 elif retain:
4328 cmdStr += "-r " + str( setName ) + " " + str( values )
4329 else:
4330 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004331 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004332 if clear:
4333 pattern = "Set " + str( setName ) + " cleared"
4334 if re.search( pattern, output ):
4335 return main.TRUE
4336 elif retain:
4337 positivePattern = str( setName ) + " was pruned to contain " +\
4338 "only elements of set \[(.*)\]"
4339 negativePattern = str( setName ) + " was not changed by " +\
4340 "retaining only elements of the set " +\
4341 "\[(.*)\]"
4342 if re.search( positivePattern, output ):
4343 return main.TRUE
4344 elif re.search( negativePattern, output ):
4345 return main.FALSE
4346 else:
4347 positivePattern = "\[(.*)\] was removed from the set " +\
4348 str( setName )
4349 if ( len( values.split() ) == 1 ):
4350 negativePattern = "\[(.*)\] was not in set " +\
4351 str( setName )
4352 else:
4353 negativePattern = "No element of \[(.*)\] was in set " +\
4354 str( setName )
4355 if re.search( positivePattern, output ):
4356 return main.TRUE
4357 elif re.search( negativePattern, output ):
4358 return main.FALSE
4359 main.log.error( self.name + ": setTestRemove did not" +
4360 " match expected output" )
4361 main.log.debug( self.name + " expected: " + pattern )
4362 main.log.debug( self.name + " actual: " + repr( output ) )
4363 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004364 except TypeError:
4365 main.log.exception( self.name + ": Object not as expected" )
4366 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004367 except Exception:
4368 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004369 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004370
4371 def setTestGet( self, setName, values="" ):
4372 """
4373 CLI command to get the elements in a distributed set.
4374 Required arguments:
4375 setName - The name of the set to remove from.
4376 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004377 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004378 returns:
4379 main.ERROR on error OR
4380 A list of elements in the set if no optional arguments are
4381 supplied OR
4382 A tuple containing the list then:
4383 main.FALSE if the given values are not in the set OR
4384 main.TRUE if the given values are in the set OR
4385 """
4386 try:
4387 values = str( values ).strip()
4388 setName = str( setName ).strip()
4389 length = len( values.split() )
4390 containsCheck = None
4391 # Patterns to match
4392 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004393 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004394 containsTrue = "Set " + setName + " contains the value " + values
4395 containsFalse = "Set " + setName + " did not contain the value " +\
4396 values
4397 containsAllTrue = "Set " + setName + " contains the the subset " +\
4398 setPattern
4399 containsAllFalse = "Set " + setName + " did not contain the the" +\
4400 " subset " + setPattern
4401
4402 cmdStr = "set-test-get "
4403 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004404 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004405 if length == 0:
4406 match = re.search( pattern, output )
4407 else: # if given values
4408 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004409 patternTrue = pattern + "\r\n" + containsTrue
4410 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004411 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004412 patternTrue = pattern + "\r\n" + containsAllTrue
4413 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004414 matchTrue = re.search( patternTrue, output )
4415 matchFalse = re.search( patternFalse, output )
4416 if matchTrue:
4417 containsCheck = main.TRUE
4418 match = matchTrue
4419 elif matchFalse:
4420 containsCheck = main.FALSE
4421 match = matchFalse
4422 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004423 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004424 "expected output" )
4425 main.log.debug( self.name + " expected: " + pattern )
4426 main.log.debug( self.name + " actual: " + repr( output ) )
4427 match = None
4428 if match:
4429 setMatch = match.group( 1 )
4430 if setMatch == '':
4431 setList = []
4432 else:
4433 setList = setMatch.split( ", " )
4434 if length > 0:
4435 return ( setList, containsCheck )
4436 else:
4437 return setList
4438 else: # no match
4439 main.log.error( self.name + ": setTestGet did not" +
4440 " match expected output" )
4441 main.log.debug( self.name + " expected: " + pattern )
4442 main.log.debug( self.name + " actual: " + repr( output ) )
4443 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004444 except TypeError:
4445 main.log.exception( self.name + ": Object not as expected" )
4446 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004447 except Exception:
4448 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004449 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004450
4451 def setTestSize( self, setName ):
4452 """
4453 CLI command to get the elements in a distributed set.
4454 Required arguments:
4455 setName - The name of the set to remove from.
4456 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004457 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004458 None on error
4459 """
4460 try:
4461 # TODO: Should this check against the number of elements returned
4462 # and then return true/false based on that?
4463 setName = str( setName ).strip()
4464 # Patterns to match
4465 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004466 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004467 setPattern
4468 cmdStr = "set-test-get -s "
4469 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004470 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004471 if output:
4472 match = re.search( pattern, output )
4473 if match:
4474 setSize = int( match.group( 1 ) )
4475 setMatch = match.group( 2 )
4476 if len( setMatch.split() ) == setSize:
4477 main.log.info( "The size returned by " + self.name +
4478 " matches the number of elements in " +
4479 "the returned set" )
4480 else:
4481 main.log.error( "The size returned by " + self.name +
4482 " does not match the number of " +
4483 "elements in the returned set." )
4484 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004485 else: # no match
4486 main.log.error( self.name + ": setTestGet did not" +
4487 " match expected output" )
4488 main.log.debug( self.name + " expected: " + pattern )
4489 main.log.debug( self.name + " actual: " + repr( output ) )
4490 return None
Jon Hall390696c2015-05-05 17:13:41 -07004491 except TypeError:
4492 main.log.exception( self.name + ": Object not as expected" )
4493 return None
Jon Hall390696c2015-05-05 17:13:41 -07004494 except Exception:
4495 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004496 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004497
Jon Hall80daded2015-05-27 16:07:00 -07004498 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004499 """
4500 Command to list the various counters in the system.
4501 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004502 if jsonFormat, a string of the json object returned by the cli
4503 command
4504 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004505 None on error
4506 """
Jon Hall390696c2015-05-05 17:13:41 -07004507 try:
Jon Hall390696c2015-05-05 17:13:41 -07004508 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004509 if jsonFormat:
4510 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004511 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004512 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004513 assert "Command not found:" not in output, output
4514 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004515 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004516 return output
Jon Hall390696c2015-05-05 17:13:41 -07004517 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004518 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004519 return None
Jon Hall390696c2015-05-05 17:13:41 -07004520 except TypeError:
4521 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004522 return None
Jon Hall390696c2015-05-05 17:13:41 -07004523 except pexpect.EOF:
4524 main.log.error( self.name + ": EOF exception found" )
4525 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004526 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004527 except Exception:
4528 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004529 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004530
Jon Hall935db192016-04-19 00:22:04 -07004531 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004532 """
Jon Halle1a3b752015-07-22 13:02:46 -07004533 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004534 Required arguments:
4535 counter - The name of the counter to increment.
4536 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004537 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004538 returns:
4539 integer value of the counter or
4540 None on Error
4541 """
4542 try:
4543 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004544 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004545 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004546 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004547 if delta != 1:
4548 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004549 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004550 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004551 match = re.search( pattern, output )
4552 if match:
4553 return int( match.group( 1 ) )
4554 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004555 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004556 " match expected output." )
4557 main.log.debug( self.name + " expected: " + pattern )
4558 main.log.debug( self.name + " actual: " + repr( output ) )
4559 return None
Jon Hall390696c2015-05-05 17:13:41 -07004560 except TypeError:
4561 main.log.exception( self.name + ": Object not as expected" )
4562 return None
Jon Hall390696c2015-05-05 17:13:41 -07004563 except Exception:
4564 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004565 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004566
Jon Hall935db192016-04-19 00:22:04 -07004567 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004568 """
4569 CLI command to get a distributed counter then add a delta to it.
4570 Required arguments:
4571 counter - The name of the counter to increment.
4572 Optional arguments:
4573 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004574 returns:
4575 integer value of the counter or
4576 None on Error
4577 """
4578 try:
4579 counter = str( counter )
4580 delta = int( delta )
4581 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004582 cmdStr += counter
4583 if delta != 1:
4584 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004585 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004586 pattern = counter + " was updated to (-?\d+)"
4587 match = re.search( pattern, output )
4588 if match:
4589 return int( match.group( 1 ) )
4590 else:
4591 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4592 " match expected output." )
4593 main.log.debug( self.name + " expected: " + pattern )
4594 main.log.debug( self.name + " actual: " + repr( output ) )
4595 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004596 except TypeError:
4597 main.log.exception( self.name + ": Object not as expected" )
4598 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004599 except Exception:
4600 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004601 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004602
4603 def valueTestGet( self, valueName ):
4604 """
4605 CLI command to get the value of an atomic value.
4606 Required arguments:
4607 valueName - The name of the value to get.
4608 returns:
4609 string value of the value or
4610 None on Error
4611 """
4612 try:
4613 valueName = str( valueName )
4614 cmdStr = "value-test "
4615 operation = "get"
4616 cmdStr = "value-test {} {}".format( valueName,
4617 operation )
4618 output = self.distPrimitivesSend( cmdStr )
4619 pattern = "(\w+)"
4620 match = re.search( pattern, output )
4621 if match:
4622 return match.group( 1 )
4623 else:
4624 main.log.error( self.name + ": valueTestGet did not" +
4625 " match expected output." )
4626 main.log.debug( self.name + " expected: " + pattern )
4627 main.log.debug( self.name + " actual: " + repr( output ) )
4628 return None
4629 except TypeError:
4630 main.log.exception( self.name + ": Object not as expected" )
4631 return None
4632 except Exception:
4633 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004634 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004635
4636 def valueTestSet( self, valueName, newValue ):
4637 """
4638 CLI command to set the value of an atomic value.
4639 Required arguments:
4640 valueName - The name of the value to set.
4641 newValue - The value to assign to the given value.
4642 returns:
4643 main.TRUE on success or
4644 main.ERROR on Error
4645 """
4646 try:
4647 valueName = str( valueName )
4648 newValue = str( newValue )
4649 operation = "set"
4650 cmdStr = "value-test {} {} {}".format( valueName,
4651 operation,
4652 newValue )
4653 output = self.distPrimitivesSend( cmdStr )
4654 if output is not None:
4655 return main.TRUE
4656 else:
4657 return main.ERROR
4658 except TypeError:
4659 main.log.exception( self.name + ": Object not as expected" )
4660 return main.ERROR
4661 except Exception:
4662 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004663 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004664
4665 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4666 """
4667 CLI command to compareAndSet the value of an atomic value.
4668 Required arguments:
4669 valueName - The name of the value.
4670 oldValue - Compare the current value of the atomic value to this
4671 newValue - If the value equals oldValue, set the value to newValue
4672 returns:
4673 main.TRUE on success or
4674 main.FALSE on failure or
4675 main.ERROR on Error
4676 """
4677 try:
4678 valueName = str( valueName )
4679 oldValue = str( oldValue )
4680 newValue = str( newValue )
4681 operation = "compareAndSet"
4682 cmdStr = "value-test {} {} {} {}".format( valueName,
4683 operation,
4684 oldValue,
4685 newValue )
4686 output = self.distPrimitivesSend( cmdStr )
4687 pattern = "(\w+)"
4688 match = re.search( pattern, output )
4689 if match:
4690 result = match.group( 1 )
4691 if result == "true":
4692 return main.TRUE
4693 elif result == "false":
4694 return main.FALSE
4695 else:
4696 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4697 " match expected output." )
4698 main.log.debug( self.name + " expected: " + pattern )
4699 main.log.debug( self.name + " actual: " + repr( output ) )
4700 return main.ERROR
4701 except TypeError:
4702 main.log.exception( self.name + ": Object not as expected" )
4703 return main.ERROR
4704 except Exception:
4705 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004706 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004707
4708 def valueTestGetAndSet( self, valueName, newValue ):
4709 """
4710 CLI command to getAndSet the value of an atomic value.
4711 Required arguments:
4712 valueName - The name of the value to get.
4713 newValue - The value to assign to the given value
4714 returns:
4715 string value of the value or
4716 None on Error
4717 """
4718 try:
4719 valueName = str( valueName )
4720 cmdStr = "value-test "
4721 operation = "getAndSet"
4722 cmdStr += valueName + " " + operation
4723 cmdStr = "value-test {} {} {}".format( valueName,
4724 operation,
4725 newValue )
4726 output = self.distPrimitivesSend( cmdStr )
4727 pattern = "(\w+)"
4728 match = re.search( pattern, output )
4729 if match:
4730 return match.group( 1 )
4731 else:
4732 main.log.error( self.name + ": valueTestGetAndSet did not" +
4733 " match expected output." )
4734 main.log.debug( self.name + " expected: " + pattern )
4735 main.log.debug( self.name + " actual: " + repr( output ) )
4736 return None
4737 except TypeError:
4738 main.log.exception( self.name + ": Object not as expected" )
4739 return None
4740 except Exception:
4741 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004742 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004743
4744 def valueTestDestroy( self, valueName ):
4745 """
4746 CLI command to destroy an atomic value.
4747 Required arguments:
4748 valueName - The name of the value to destroy.
4749 returns:
4750 main.TRUE on success or
4751 main.ERROR on Error
4752 """
4753 try:
4754 valueName = str( valueName )
4755 cmdStr = "value-test "
4756 operation = "destroy"
4757 cmdStr += valueName + " " + operation
4758 output = self.distPrimitivesSend( cmdStr )
4759 if output is not None:
4760 return main.TRUE
4761 else:
4762 return main.ERROR
4763 except TypeError:
4764 main.log.exception( self.name + ": Object not as expected" )
4765 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004766 except Exception:
4767 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004768 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004769
YPZhangfebf7302016-05-24 16:45:56 -07004770 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004771 """
4772 Description: Execute summary command in onos
4773 Returns: json object ( summary -j ), returns main.FALSE if there is
4774 no output
4775
4776 """
4777 try:
4778 cmdStr = "summary"
4779 if jsonFormat:
4780 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004781 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004782 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004783 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004784 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004785 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004786 if not handle:
4787 main.log.error( self.name + ": There is no output in " +
4788 "summary command" )
4789 return main.FALSE
4790 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004791 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004792 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004793 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004794 except TypeError:
4795 main.log.exception( self.name + ": Object not as expected" )
4796 return None
4797 except pexpect.EOF:
4798 main.log.error( self.name + ": EOF exception found" )
4799 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004800 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004801 except Exception:
4802 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004803 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004804
Jon Hall935db192016-04-19 00:22:04 -07004805 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004806 """
4807 CLI command to get the value of a key in a consistent map using
4808 transactions. This a test function and can only get keys from the
4809 test map hard coded into the cli command
4810 Required arguments:
4811 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004812 returns:
4813 The string value of the key or
4814 None on Error
4815 """
4816 try:
4817 keyName = str( keyName )
4818 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004819 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004820 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004821 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4822 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004823 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004824 return None
4825 else:
4826 match = re.search( pattern, output )
4827 if match:
4828 return match.groupdict()[ 'value' ]
4829 else:
4830 main.log.error( self.name + ": transactionlMapGet did not" +
4831 " match expected output." )
4832 main.log.debug( self.name + " expected: " + pattern )
4833 main.log.debug( self.name + " actual: " + repr( output ) )
4834 return None
4835 except TypeError:
4836 main.log.exception( self.name + ": Object not as expected" )
4837 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004838 except Exception:
4839 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004840 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004841
Jon Hall935db192016-04-19 00:22:04 -07004842 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004843 """
4844 CLI command to put a value into 'numKeys' number of keys in a
4845 consistent map using transactions. This a test function and can only
4846 put into keys named 'Key#' of the test map hard coded into the cli command
4847 Required arguments:
4848 numKeys - Number of keys to add the value to
4849 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004850 returns:
4851 A dictionary whose keys are the name of the keys put into the map
4852 and the values of the keys are dictionaries whose key-values are
4853 'value': value put into map and optionaly
4854 'oldValue': Previous value in the key or
4855 None on Error
4856
4857 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004858 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4859 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004860 """
4861 try:
4862 numKeys = str( numKeys )
4863 value = str( value )
4864 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004865 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004866 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004867 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4868 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4869 results = {}
4870 for line in output.splitlines():
4871 new = re.search( newPattern, line )
4872 updated = re.search( updatedPattern, line )
4873 if new:
4874 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4875 elif updated:
4876 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004877 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004878 else:
4879 main.log.error( self.name + ": transactionlMapGet did not" +
4880 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004881 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4882 newPattern,
4883 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004884 main.log.debug( self.name + " actual: " + repr( output ) )
4885 return results
Jon Hall0e240372018-05-02 11:21:57 -07004886 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004887 main.log.exception( self.name + ": Object not as expected" )
4888 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004889 except Exception:
4890 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004891 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004892
acsmarsdaea66c2015-09-03 11:44:06 -07004893 def maps( self, jsonFormat=True ):
4894 """
4895 Description: Returns result of onos:maps
4896 Optional:
4897 * jsonFormat: enable json formatting of output
4898 """
4899 try:
4900 cmdStr = "maps"
4901 if jsonFormat:
4902 cmdStr += " -j"
4903 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004904 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004905 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004906 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004907 except AssertionError:
4908 main.log.exception( "" )
4909 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004910 except TypeError:
4911 main.log.exception( self.name + ": Object not as expected" )
4912 return None
4913 except pexpect.EOF:
4914 main.log.error( self.name + ": EOF exception found" )
4915 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004916 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004917 except Exception:
4918 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004919 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004920
4921 def getSwController( self, uri, jsonFormat=True ):
4922 """
4923 Descrition: Gets the controller information from the device
4924 """
4925 try:
4926 cmd = "device-controllers "
4927 if jsonFormat:
4928 cmd += "-j "
4929 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004930 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004931 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004932 return response
Jon Hallc6793552016-01-19 14:18:37 -08004933 except AssertionError:
4934 main.log.exception( "" )
4935 return None
GlennRC050596c2015-11-18 17:06:41 -08004936 except TypeError:
4937 main.log.exception( self.name + ": Object not as expected" )
4938 return None
4939 except pexpect.EOF:
4940 main.log.error( self.name + ": EOF exception found" )
4941 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004942 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004943 except Exception:
4944 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004945 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004946
4947 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4948 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004949 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004950
4951 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004952 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08004953 ip - String or List: The ip address of the controller.
4954 This parameter can be formed in a couple of different ways.
4955 VALID:
4956 10.0.0.1 - just the ip address
4957 tcp:10.0.0.1 - the protocol and the ip address
4958 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4959 so that you can add controllers with different
4960 protocols and ports
4961 INVALID:
4962 10.0.0.1:6653 - this is not supported by ONOS
4963
4964 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4965 port - The port number.
4966 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4967
4968 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4969 """
4970 try:
4971 cmd = "device-setcontrollers"
4972
4973 if jsonFormat:
4974 cmd += " -j"
4975 cmd += " " + uri
4976 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004977 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08004978 for item in ip:
4979 if ":" in item:
4980 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004981 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08004982 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004983 elif "." in sitem[ 1 ]:
4984 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08004985 else:
4986 main.log.error( "Malformed entry: " + item )
4987 raise TypeError
4988 else:
4989 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004990 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004991 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004992 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004993 if "Error" in response:
4994 main.log.error( response )
4995 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004996 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004997 except AssertionError:
4998 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004999 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08005000 except TypeError:
5001 main.log.exception( self.name + ": Object not as expected" )
5002 return main.FALSE
5003 except pexpect.EOF:
5004 main.log.error( self.name + ": EOF exception found" )
5005 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005006 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005007 except Exception:
5008 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005009 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005010
5011 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005012 '''
GlennRC20fc6522015-12-23 23:26:57 -08005013 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005014 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005015 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005016 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005017 Returns:
5018 Returns main.FALSE if an exception is thrown or an error is present
5019 in the response. Otherwise, returns main.TRUE.
5020 NOTE:
5021 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005022 '''
GlennRC20fc6522015-12-23 23:26:57 -08005023 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005024 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005025 deviceStr = device
5026 device = []
5027 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005028
5029 for d in device:
5030 time.sleep( 1 )
5031 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005032 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005033 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005034 if "Error" in response:
5035 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5036 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005037 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005038 except AssertionError:
5039 main.log.exception( "" )
5040 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005041 except TypeError:
5042 main.log.exception( self.name + ": Object not as expected" )
5043 return main.FALSE
5044 except pexpect.EOF:
5045 main.log.error( self.name + ": EOF exception found" )
5046 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005047 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005048 except Exception:
5049 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005050 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005051
5052 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005053 '''
GlennRC20fc6522015-12-23 23:26:57 -08005054 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005055 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005056 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005057 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005058 Returns:
5059 Returns main.FALSE if an exception is thrown or an error is present
5060 in the response. Otherwise, returns main.TRUE.
5061 NOTE:
5062 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005063 '''
GlennRC20fc6522015-12-23 23:26:57 -08005064 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005065 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005066 host = list( host )
5067
5068 for h in host:
5069 time.sleep( 1 )
5070 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005071 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005072 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005073 if "Error" in response:
5074 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5075 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005076 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005077 except AssertionError:
5078 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005079 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005080 except TypeError:
5081 main.log.exception( self.name + ": Object not as expected" )
5082 return main.FALSE
5083 except pexpect.EOF:
5084 main.log.error( self.name + ": EOF exception found" )
5085 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005086 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005087 except Exception:
5088 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005089 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005090
YPZhangfebf7302016-05-24 16:45:56 -07005091 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005092 '''
GlennRCed771242016-01-13 17:02:47 -08005093 Description:
5094 Bring link down or up in the null-provider.
5095 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005096 begin - (string) One end of a device or switch.
5097 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005098 returns:
5099 main.TRUE if no exceptions were thrown and no Errors are
5100 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005101 '''
GlennRCed771242016-01-13 17:02:47 -08005102 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005103 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005104 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005105 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005106 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005107 if "Error" in response or "Failure" in response:
5108 main.log.error( response )
5109 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005110 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005111 except AssertionError:
5112 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005113 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005114 except TypeError:
5115 main.log.exception( self.name + ": Object not as expected" )
5116 return main.FALSE
5117 except pexpect.EOF:
5118 main.log.error( self.name + ": EOF exception found" )
5119 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005120 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005121 except Exception:
5122 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005123 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005124
Jon Hall2c8959e2016-12-16 12:17:34 -08005125 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005126 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005127 Description:
5128 Changes the state of port in an OF switch by means of the
5129 PORTSTATUS OF messages.
5130 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005131 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5132 port - (string) target port in the device. Ex: '2'
5133 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005134 returns:
5135 main.TRUE if no exceptions were thrown and no Errors are
5136 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005137 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005138 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005139 state = state.lower()
5140 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005141 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005142 response = self.sendline( cmd, showResponse=True )
5143 assert response is not None, "Error in sendline"
5144 assert "Command not found:" not in response, response
5145 if "Error" in response or "Failure" in response:
5146 main.log.error( response )
5147 return main.FALSE
5148 return main.TRUE
5149 except AssertionError:
5150 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005151 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005152 except TypeError:
5153 main.log.exception( self.name + ": Object not as expected" )
5154 return main.FALSE
5155 except pexpect.EOF:
5156 main.log.error( self.name + ": EOF exception found" )
5157 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005158 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005159 except Exception:
5160 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005161 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005162
5163 def logSet( self, level="INFO", app="org.onosproject" ):
5164 """
5165 Set the logging level to lvl for a specific app
5166 returns main.TRUE on success
5167 returns main.FALSE if Error occurred
5168 if noExit is True, TestON will not exit, but clean up
5169 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5170 Level defaults to INFO
5171 """
5172 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005173 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005174 self.handle.expect( "onos>" )
5175
5176 response = self.handle.before
5177 if re.search( "Error", response ):
5178 return main.FALSE
5179 return main.TRUE
5180 except pexpect.TIMEOUT:
5181 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005182 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005183 except pexpect.EOF:
5184 main.log.error( self.name + ": EOF exception found" )
5185 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005186 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005187 except Exception:
5188 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005189 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005190
5191 def getGraphDict( self, timeout=60, includeHost=False ):
5192 """
5193 Return a dictionary which describes the latest network topology data as a
5194 graph.
5195 An example of the dictionary:
5196 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5197 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5198 Each vertex should at least have an 'edges' attribute which describes the
5199 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005200 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005201 list of attributes.
5202 An example of the edges dictionary:
5203 'edges': { vertex2: { 'port': ..., 'weight': ... },
5204 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005205 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005206 in topology data.
5207 """
5208 graphDict = {}
5209 try:
5210 links = self.links()
5211 links = json.loads( links )
5212 devices = self.devices()
5213 devices = json.loads( devices )
5214 idToDevice = {}
5215 for device in devices:
5216 idToDevice[ device[ 'id' ] ] = device
5217 if includeHost:
5218 hosts = self.hosts()
5219 # FIXME: support 'includeHost' argument
5220 for link in links:
5221 nodeA = link[ 'src' ][ 'device' ]
5222 nodeB = link[ 'dst' ][ 'device' ]
5223 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005224 if nodeA not in graphDict.keys():
5225 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005226 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005227 'type': idToDevice[ nodeA ][ 'type' ],
5228 'available': idToDevice[ nodeA ][ 'available' ],
5229 'role': idToDevice[ nodeA ][ 'role' ],
5230 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5231 'hw': idToDevice[ nodeA ][ 'hw' ],
5232 'sw': idToDevice[ nodeA ][ 'sw' ],
5233 'serial': idToDevice[ nodeA ][ 'serial' ],
5234 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005235 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005236 else:
5237 # Assert nodeB is not connected to any current links of nodeA
5238 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005239 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5240 'type': link[ 'type' ],
5241 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005242 return graphDict
5243 except ( TypeError, ValueError ):
5244 main.log.exception( self.name + ": Object not as expected" )
5245 return None
5246 except KeyError:
5247 main.log.exception( self.name + ": KeyError exception found" )
5248 return None
5249 except AssertionError:
5250 main.log.exception( self.name + ": AssertionError exception found" )
5251 return None
5252 except pexpect.EOF:
5253 main.log.error( self.name + ": EOF exception found" )
5254 main.log.error( self.name + ": " + self.handle.before )
5255 return None
5256 except Exception:
5257 main.log.exception( self.name + ": Uncaught exception!" )
5258 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005259
5260 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005261 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005262 Send command to check intent-perf summary
5263 Returns: dictionary for intent-perf summary
5264 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005265 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005266 cmd = "intent-perf -s"
5267 respDic = {}
5268 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005269 assert resp is not None, "Error in sendline"
5270 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005271 try:
5272 # Generate the dictionary to return
5273 for l in resp.split( "\n" ):
5274 # Delete any white space in line
5275 temp = re.sub( r'\s+', '', l )
5276 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005277 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005278
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005279 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005280 main.log.exception( self.name + ": Object not as expected" )
5281 return None
5282 except KeyError:
5283 main.log.exception( self.name + ": KeyError exception found" )
5284 return None
5285 except AssertionError:
5286 main.log.exception( self.name + ": AssertionError exception found" )
5287 return None
5288 except pexpect.EOF:
5289 main.log.error( self.name + ": EOF exception found" )
5290 main.log.error( self.name + ": " + self.handle.before )
5291 return None
5292 except Exception:
5293 main.log.exception( self.name + ": Uncaught exception!" )
5294 return None
5295 return respDic
5296
Chiyu Chengec63bde2016-11-17 18:11:36 -08005297 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005298 """
5299 Searches the latest ONOS log file for the given search term and
5300 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005301
chengchiyu08303a02016-09-08 17:40:26 -07005302 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005303 searchTerm:
5304 The string to grep from the ONOS log.
5305 startLine:
5306 The term that decides which line is the start to search the searchTerm in
5307 the karaf log. For now, startTerm only works in 'first' mode.
5308 logNum:
5309 In some extreme cases, one karaf log is not big enough to contain all the
5310 information.Because of this, search mutiply logs is necessary to capture
5311 the right result. logNum is the number of karaf logs that we need to search
5312 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005313 mode:
5314 all: return all the strings that contain the search term
5315 last: return the last string that contains the search term
5316 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005317 num: return the number of times that the searchTerm appears in the log
5318 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005319 """
5320 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005321 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005322 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005323 logPath = '/opt/onos/log/karaf.log.'
5324 logPaths = '/opt/onos/log/karaf.log'
5325 for i in range( 1, logNum ):
5326 logPaths = logPath + str( i ) + " " + logPaths
5327 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005328 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005329 # 100000000 is just a extreme large number to make sure this function can
5330 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005331 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005332 if mode == 'all':
5333 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005334 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005335 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005336 elif mode == 'first':
5337 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5338 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005339 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005340 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005341 return num
You Wang6d301d42017-04-21 10:49:33 -07005342 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005343 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005344 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005345 else:
5346 main.log.error( self.name + " unsupported mode" )
5347 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005348 before = self.sendline( cmd )
5349 before = before.splitlines()
5350 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005351 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005352 return returnLines
5353 except AssertionError:
5354 main.log.error( self.name + " searchTerm is not string type" )
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 )
Devin Lim44075962017-08-11 10:56:37 -07005359 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005360 except pexpect.TIMEOUT:
5361 main.log.error( self.name + ": TIMEOUT exception found" )
5362 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005363 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005364 except Exception:
5365 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005366 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005367
5368 def vplsShow( self, jsonFormat=True ):
5369 """
5370 Description: Returns result of onos:vpls show, which should list the
5371 configured VPLS networks and the assigned interfaces.
5372 Optional:
5373 * jsonFormat: enable json formatting of output
5374 Returns:
5375 The output of the command or None on error.
5376 """
5377 try:
5378 cmdStr = "vpls show"
5379 if jsonFormat:
5380 raise NotImplementedError
5381 cmdStr += " -j"
5382 handle = self.sendline( cmdStr )
5383 assert handle is not None, "Error in sendline"
5384 assert "Command not found:" not in handle, handle
5385 return handle
5386 except AssertionError:
5387 main.log.exception( "" )
5388 return None
5389 except TypeError:
5390 main.log.exception( self.name + ": Object not as expected" )
5391 return None
5392 except pexpect.EOF:
5393 main.log.error( self.name + ": EOF exception found" )
5394 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005395 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005396 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005397 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005398 return None
5399 except Exception:
5400 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005401 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005402
5403 def parseVplsShow( self ):
5404 """
5405 Parse the cli output of 'vpls show' into json output. This is required
5406 as there is currently no json output available.
5407 """
5408 try:
5409 output = []
5410 raw = self.vplsShow( jsonFormat=False )
5411 namePat = "VPLS name: (?P<name>\w+)"
5412 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5413 encapPat = "Encapsulation: (?P<encap>\w+)"
5414 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5415 mIter = re.finditer( pattern, raw )
5416 for match in mIter:
5417 item = {}
5418 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005419 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005420 if ifaces == [ "" ]:
5421 ifaces = []
5422 item[ 'interfaces' ] = ifaces
5423 encap = match.group( 'encap' )
5424 if encap != 'NONE':
5425 item[ 'encapsulation' ] = encap.lower()
5426 output.append( item )
5427 return output
5428 except Exception:
5429 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005430 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005431
5432 def vplsList( self, jsonFormat=True ):
5433 """
5434 Description: Returns result of onos:vpls list, which should list the
5435 configured VPLS networks.
5436 Optional:
5437 * jsonFormat: enable json formatting of output
5438 """
5439 try:
5440 cmdStr = "vpls list"
5441 if jsonFormat:
5442 raise NotImplementedError
5443 cmdStr += " -j"
5444 handle = self.sendline( cmdStr )
5445 assert handle is not None, "Error in sendline"
5446 assert "Command not found:" not in handle, handle
5447 return handle
5448 except AssertionError:
5449 main.log.exception( "" )
5450 return None
5451 except TypeError:
5452 main.log.exception( self.name + ": Object not as expected" )
5453 return None
5454 except pexpect.EOF:
5455 main.log.error( self.name + ": EOF exception found" )
5456 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005457 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005458 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005459 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005460 return None
5461 except Exception:
5462 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005463 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005464
5465 def vplsCreate( self, network ):
5466 """
5467 CLI command to create a new VPLS network.
5468 Required arguments:
5469 network - String name of the network to create.
5470 returns:
5471 main.TRUE on success and main.FALSE on failure
5472 """
5473 try:
5474 network = str( network )
5475 cmdStr = "vpls create "
5476 cmdStr += network
5477 output = self.sendline( cmdStr )
5478 assert output is not None, "Error in sendline"
5479 assert "Command not found:" not in output, output
5480 assert "Error executing command" not in output, output
5481 assert "VPLS already exists:" not in output, output
5482 return main.TRUE
5483 except AssertionError:
5484 main.log.exception( "" )
5485 return main.FALSE
5486 except TypeError:
5487 main.log.exception( self.name + ": Object not as expected" )
5488 return main.FALSE
5489 except pexpect.EOF:
5490 main.log.error( self.name + ": EOF exception found" )
5491 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005492 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005493 except Exception:
5494 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005495 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005496
5497 def vplsDelete( self, network ):
5498 """
5499 CLI command to delete a VPLS network.
5500 Required arguments:
5501 network - Name of the network to delete.
5502 returns:
5503 main.TRUE on success and main.FALSE on failure
5504 """
5505 try:
5506 network = str( network )
5507 cmdStr = "vpls delete "
5508 cmdStr += network
5509 output = self.sendline( cmdStr )
5510 assert output is not None, "Error in sendline"
5511 assert "Command not found:" not in output, output
5512 assert "Error executing command" not in output, output
5513 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005514 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005515 return main.TRUE
5516 except AssertionError:
5517 main.log.exception( "" )
5518 return main.FALSE
5519 except TypeError:
5520 main.log.exception( self.name + ": Object not as expected" )
5521 return main.FALSE
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 Exception:
5527 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005528 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005529
5530 def vplsAddIface( self, network, iface ):
5531 """
5532 CLI command to add an interface to a VPLS network.
5533 Required arguments:
5534 network - Name of the network to add the interface to.
5535 iface - The ONOS name for an interface.
5536 returns:
5537 main.TRUE on success and main.FALSE on failure
5538 """
5539 try:
5540 network = str( network )
5541 iface = str( iface )
5542 cmdStr = "vpls add-if "
5543 cmdStr += network + " " + iface
5544 output = self.sendline( cmdStr )
5545 assert output is not None, "Error in sendline"
5546 assert "Command not found:" not in output, output
5547 assert "Error executing command" not in output, output
5548 assert "already associated to network" not in output, output
5549 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005550 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005551 return main.TRUE
5552 except AssertionError:
5553 main.log.exception( "" )
5554 return main.FALSE
5555 except TypeError:
5556 main.log.exception( self.name + ": Object not as expected" )
5557 return main.FALSE
5558 except pexpect.EOF:
5559 main.log.error( self.name + ": EOF exception found" )
5560 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005561 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005562 except Exception:
5563 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005564 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005565
5566 def vplsRemIface( self, network, iface ):
5567 """
5568 CLI command to remove an interface from a VPLS network.
5569 Required arguments:
5570 network - Name of the network to remove the interface from.
5571 iface - Name of the interface to remove.
5572 returns:
5573 main.TRUE on success and main.FALSE on failure
5574 """
5575 try:
5576 iface = str( iface )
5577 cmdStr = "vpls rem-if "
5578 cmdStr += network + " " + iface
5579 output = self.sendline( cmdStr )
5580 assert output is not None, "Error in sendline"
5581 assert "Command not found:" not in output, output
5582 assert "Error executing command" not in output, output
5583 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005584 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005585 return main.TRUE
5586 except AssertionError:
5587 main.log.exception( "" )
5588 return main.FALSE
5589 except TypeError:
5590 main.log.exception( self.name + ": Object not as expected" )
5591 return main.FALSE
5592 except pexpect.EOF:
5593 main.log.error( self.name + ": EOF exception found" )
5594 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005595 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005596 except Exception:
5597 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005598 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005599
5600 def vplsClean( self ):
5601 """
5602 Description: Clears the VPLS app configuration.
5603 Returns: main.TRUE on success and main.FALSE on failure
5604 """
5605 try:
5606 cmdStr = "vpls clean"
5607 handle = self.sendline( cmdStr )
5608 assert handle is not None, "Error in sendline"
5609 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005610 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005611 return handle
5612 except AssertionError:
5613 main.log.exception( "" )
5614 return main.FALSE
5615 except TypeError:
5616 main.log.exception( self.name + ": Object not as expected" )
5617 return main.FALSE
5618 except pexpect.EOF:
5619 main.log.error( self.name + ": EOF exception found" )
5620 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005621 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005622 except Exception:
5623 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005624 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005625
5626 def vplsSetEncap( self, network, encapType ):
5627 """
5628 CLI command to add an interface to a VPLS network.
5629 Required arguments:
5630 network - Name of the network to create.
5631 encapType - Type of encapsulation.
5632 returns:
5633 main.TRUE on success and main.FALSE on failure
5634 """
5635 try:
5636 network = str( network )
5637 encapType = str( encapType ).upper()
5638 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5639 cmdStr = "vpls set-encap "
5640 cmdStr += network + " " + encapType
5641 output = self.sendline( cmdStr )
5642 assert output is not None, "Error in sendline"
5643 assert "Command not found:" not in output, output
5644 assert "Error executing command" not in output, output
5645 assert "already associated to network" not in output, output
5646 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005647 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005648 return main.TRUE
5649 except AssertionError:
5650 main.log.exception( "" )
5651 return main.FALSE
5652 except TypeError:
5653 main.log.exception( self.name + ": Object not as expected" )
5654 return main.FALSE
5655 except pexpect.EOF:
5656 main.log.error( self.name + ": EOF exception found" )
5657 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005658 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005659 except Exception:
5660 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005661 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005662
5663 def interfaces( self, jsonFormat=True ):
5664 """
5665 Description: Returns result of interfaces command.
5666 Optional:
5667 * jsonFormat: enable json formatting of output
5668 Returns:
5669 The output of the command or None on error.
5670 """
5671 try:
5672 cmdStr = "interfaces"
5673 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005674 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005675 cmdStr += " -j"
5676 handle = self.sendline( cmdStr )
5677 assert handle is not None, "Error in sendline"
5678 assert "Command not found:" not in handle, handle
5679 return handle
5680 except AssertionError:
5681 main.log.exception( "" )
5682 return None
5683 except TypeError:
5684 main.log.exception( self.name + ": Object not as expected" )
5685 return None
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 NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005691 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005692 return None
5693 except Exception:
5694 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005695 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005696
5697 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005698 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005699 Get the timestamp of searchTerm from karaf log.
5700
5701 Arguments:
5702 splitTerm_before and splitTerm_after:
5703
5704 The terms that split the string that contains the timeStamp of
5705 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5706 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5707 and the splitTerm_after is "x"
5708
5709 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005710 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005711 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005712 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005713 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005714 return main.ERROR
5715 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005716 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005717 main.log.warn( "Captured timestamp string is empty" )
5718 return main.ERROR
5719 lines = lines[ 0 ]
5720 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005721 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005722 # get the target value
5723 line = lines.split( splitTerm_before )
5724 key = line[ 1 ].split( splitTerm_after )
5725 return int( key[ 0 ] )
5726 except IndexError:
5727 main.log.warn( "Index Error!" )
5728 return main.ERROR
5729 except AssertionError:
5730 main.log.warn( "Search Term Not Found " )
5731 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005732
5733 def workQueueAdd( self, queueName, value ):
5734 """
5735 CLI command to add a string to the specified Work Queue.
5736 This function uses the distributed primitives test app, which
5737 gives some cli access to distributed primitives for testing
5738 purposes only.
5739
5740 Required arguments:
5741 queueName - The name of the queue to add to
5742 value - The value to add to the queue
5743 returns:
5744 main.TRUE on success, main.FALSE on failure and
5745 main.ERROR on error.
5746 """
5747 try:
5748 queueName = str( queueName )
5749 value = str( value )
5750 prefix = "work-queue-test"
5751 operation = "add"
5752 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5753 output = self.distPrimitivesSend( cmdStr )
5754 if "Invalid operation name" in output:
5755 main.log.warn( output )
5756 return main.ERROR
5757 elif "Done" in output:
5758 return main.TRUE
5759 except TypeError:
5760 main.log.exception( self.name + ": Object not as expected" )
5761 return main.ERROR
5762 except Exception:
5763 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005764 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005765
5766 def workQueueAddMultiple( self, queueName, value1, value2 ):
5767 """
5768 CLI command to add two strings to the specified Work Queue.
5769 This function uses the distributed primitives test app, which
5770 gives some cli access to distributed primitives for testing
5771 purposes only.
5772
5773 Required arguments:
5774 queueName - The name of the queue to add to
5775 value1 - The first value to add to the queue
5776 value2 - The second value to add to the queue
5777 returns:
5778 main.TRUE on success, main.FALSE on failure and
5779 main.ERROR on error.
5780 """
5781 try:
5782 queueName = str( queueName )
5783 value1 = str( value1 )
5784 value2 = str( value2 )
5785 prefix = "work-queue-test"
5786 operation = "addMultiple"
5787 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5788 output = self.distPrimitivesSend( cmdStr )
5789 if "Invalid operation name" in output:
5790 main.log.warn( output )
5791 return main.ERROR
5792 elif "Done" in output:
5793 return main.TRUE
5794 except TypeError:
5795 main.log.exception( self.name + ": Object not as expected" )
5796 return main.ERROR
5797 except Exception:
5798 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005799 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005800
5801 def workQueueTakeAndComplete( self, queueName, number=1 ):
5802 """
5803 CLI command to take a value from the specified Work Queue and compelte it.
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 number - The number of items to take and complete
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 number = str( int( number ) )
5818 prefix = "work-queue-test"
5819 operation = "takeAndComplete"
5820 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
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 workQueueDestroy( self, queueName ):
5835 """
5836 CLI command to destroy 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 returns:
5844 main.TRUE on success, main.FALSE on failure and
5845 main.ERROR on error.
5846 """
5847 try:
5848 queueName = str( queueName )
5849 prefix = "work-queue-test"
5850 operation = "destroy"
5851 cmdStr = " ".join( [ prefix, queueName, operation ] )
5852 output = self.distPrimitivesSend( cmdStr )
5853 if "Invalid operation name" in output:
5854 main.log.warn( output )
5855 return main.ERROR
5856 return main.TRUE
5857 except TypeError:
5858 main.log.exception( self.name + ": Object not as expected" )
5859 return main.ERROR
5860 except Exception:
5861 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005862 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005863
5864 def workQueueTotalPending( self, queueName ):
5865 """
5866 CLI command to get the Total Pending items of the specified Work Queue.
5867 This function uses the distributed primitives test app, which
5868 gives some cli access to distributed primitives for testing
5869 purposes only.
5870
5871 Required arguments:
5872 queueName - The name of the queue to add to
5873 returns:
5874 The number of Pending items in the specified work queue or
5875 None on error
5876 """
5877 try:
5878 queueName = str( queueName )
5879 prefix = "work-queue-test"
5880 operation = "totalPending"
5881 cmdStr = " ".join( [ prefix, queueName, operation ] )
5882 output = self.distPrimitivesSend( cmdStr )
5883 pattern = r'\d+'
5884 if "Invalid operation name" in output:
5885 main.log.warn( output )
5886 return None
5887 else:
5888 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005889 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005890 except ( AttributeError, TypeError ):
5891 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5892 return None
5893 except Exception:
5894 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005895 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005896
5897 def workQueueTotalCompleted( self, queueName ):
5898 """
5899 CLI command to get the Total Completed items of the specified Work Queue.
5900 This function uses the distributed primitives test app, which
5901 gives some cli access to distributed primitives for testing
5902 purposes only.
5903
5904 Required arguments:
5905 queueName - The name of the queue to add to
5906 returns:
5907 The number of complete items in the specified work queue or
5908 None on error
5909 """
5910 try:
5911 queueName = str( queueName )
5912 prefix = "work-queue-test"
5913 operation = "totalCompleted"
5914 cmdStr = " ".join( [ prefix, queueName, operation ] )
5915 output = self.distPrimitivesSend( cmdStr )
5916 pattern = r'\d+'
5917 if "Invalid operation name" in output:
5918 main.log.warn( output )
5919 return None
5920 else:
5921 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005922 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005923 except ( AttributeError, TypeError ):
5924 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5925 return None
5926 except Exception:
5927 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005928 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005929
5930 def workQueueTotalInProgress( self, queueName ):
5931 """
5932 CLI command to get the Total In Progress items of the specified Work Queue.
5933 This function uses the distributed primitives test app, which
5934 gives some cli access to distributed primitives for testing
5935 purposes only.
5936
5937 Required arguments:
5938 queueName - The name of the queue to add to
5939 returns:
5940 The number of In Progress items in the specified work queue or
5941 None on error
5942 """
5943 try:
5944 queueName = str( queueName )
5945 prefix = "work-queue-test"
5946 operation = "totalInProgress"
5947 cmdStr = " ".join( [ prefix, queueName, operation ] )
5948 output = self.distPrimitivesSend( cmdStr )
5949 pattern = r'\d+'
5950 if "Invalid operation name" in output:
5951 main.log.warn( output )
5952 return None
5953 else:
5954 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005955 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005956 except ( AttributeError, TypeError ):
5957 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5958 return None
5959 except Exception:
5960 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005961 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005962
5963 def events( self, args='-a' ):
5964 """
5965 Description: Returns events -a command output
5966 Optional:
5967 add other arguments
5968 """
5969 try:
5970 cmdStr = "events"
5971 if args:
5972 cmdStr += " " + args
5973 handle = self.sendline( cmdStr )
5974 assert handle is not None, "Error in sendline"
5975 assert "Command not found:" not in handle, handle
5976 return handle
5977 except AssertionError:
5978 main.log.exception( "" )
5979 return None
5980 except TypeError:
5981 main.log.exception( self.name + ": Object not as expected" )
5982 return None
5983 except pexpect.EOF:
5984 main.log.error( self.name + ": EOF exception found" )
5985 main.log.error( self.name + ": " + self.handle.before )
5986 main.cleanAndExit()
5987 except Exception:
5988 main.log.exception( self.name + ": Uncaught exception!" )
5989 main.cleanAndExit()
5990
5991 def getMaster( self, deviceID ):
5992 """
5993 Description: Obtains current master using "roles" command for a specific deviceID
5994 """
5995 try:
5996 return str( self.getRole( deviceID )[ 'master' ] )
5997 except AssertionError:
5998 main.log.exception( "" )
5999 return None
6000 except TypeError:
6001 main.log.exception( self.name + ": Object not as expected" )
6002 return None
6003 except pexpect.EOF:
6004 main.log.error( self.name + ": EOF exception found" )
6005 main.log.error( self.name + ": " + self.handle.before )
6006 main.cleanAndExit()
6007 except Exception:
6008 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006009 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006010
6011 def issu( self ):
6012 """
6013 Short summary of In-Service Software Upgrade status
6014
6015 Returns the output of the cli command or None on Error
6016 """
6017 try:
6018 cmdStr = "issu"
6019 handle = self.sendline( cmdStr )
6020 assert handle is not None, "Error in sendline"
6021 assert "Command not found:" not in handle, handle
6022 assert "Unsupported command:" not in handle, handle
6023 return handle
6024 except AssertionError:
6025 main.log.exception( "" )
6026 return None
6027 except TypeError:
6028 main.log.exception( self.name + ": Object not as expected" )
6029 return None
6030 except pexpect.EOF:
6031 main.log.error( self.name + ": EOF exception found" )
6032 main.log.error( self.name + ": " + self.handle.before )
6033 main.cleanAndExit()
6034 except Exception:
6035 main.log.exception( self.name + ": Uncaught exception!" )
6036 main.cleanAndExit()
6037
6038 def issuInit( self ):
6039 """
6040 Initiates an In-Service Software Upgrade
6041
6042 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6043 """
6044 try:
6045 cmdStr = "issu init"
6046 handle = self.sendline( cmdStr )
6047 assert handle is not None, "Error in sendline"
6048 assert "Command not found:" not in handle, handle
6049 assert "Unsupported command:" not in handle, handle
6050 if "Initialized" in handle:
6051 return main.TRUE
6052 else:
6053 return main.FALSE
6054 except AssertionError:
6055 main.log.exception( "" )
6056 return main.ERROR
6057 except TypeError:
6058 main.log.exception( self.name + ": Object not as expected" )
6059 return main.ERROR
6060 except pexpect.EOF:
6061 main.log.error( self.name + ": EOF exception found" )
6062 main.log.error( self.name + ": " + self.handle.before )
6063 main.cleanAndExit()
6064 except Exception:
6065 main.log.exception( self.name + ": Uncaught exception!" )
6066 main.cleanAndExit()
6067
6068 def issuUpgrade( self ):
6069 """
6070 Transitions stores to upgraded nodes
6071
6072 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6073 """
6074 try:
6075 cmdStr = "issu upgrade"
6076 handle = self.sendline( cmdStr )
6077 assert handle is not None, "Error in sendline"
6078 assert "Command not found:" not in handle, handle
6079 assert "Unsupported command:" not in handle, handle
6080 if "Upgraded" in handle:
6081 return main.TRUE
6082 else:
6083 return main.FALSE
6084 except AssertionError:
6085 main.log.exception( "" )
6086 return main.ERROR
6087 except TypeError:
6088 main.log.exception( self.name + ": Object not as expected" )
6089 return main.ERROR
6090 except pexpect.EOF:
6091 main.log.error( self.name + ": EOF exception found" )
6092 main.log.error( self.name + ": " + self.handle.before )
6093 main.cleanAndExit()
6094 except Exception:
6095 main.log.exception( self.name + ": Uncaught exception!" )
6096 main.cleanAndExit()
6097
6098 def issuCommit( self ):
6099 """
6100 Finalizes an In-Service Software Upgrade
6101
6102 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6103 """
6104 try:
6105 cmdStr = "issu commit"
6106 handle = self.sendline( cmdStr )
6107 assert handle is not None, "Error in sendline"
6108 assert "Command not found:" not in handle, handle
6109 assert "Unsupported command:" not in handle, handle
6110 # TODO: Check the version returned by this command
6111 if "Committed version" in handle:
6112 return main.TRUE
6113 else:
6114 return main.FALSE
6115 except AssertionError:
6116 main.log.exception( "" )
6117 return main.ERROR
6118 except TypeError:
6119 main.log.exception( self.name + ": Object not as expected" )
6120 return main.ERROR
6121 except pexpect.EOF:
6122 main.log.error( self.name + ": EOF exception found" )
6123 main.log.error( self.name + ": " + self.handle.before )
6124 main.cleanAndExit()
6125 except Exception:
6126 main.log.exception( self.name + ": Uncaught exception!" )
6127 main.cleanAndExit()
6128
6129 def issuRollback( self ):
6130 """
6131 Rolls back an In-Service Software Upgrade
6132
6133 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6134 """
6135 try:
6136 cmdStr = "issu rollback"
6137 handle = self.sendline( cmdStr )
6138 assert handle is not None, "Error in sendline"
6139 assert "Command not found:" not in handle, handle
6140 assert "Unsupported command:" not in handle, handle
6141 # TODO: Check the version returned by this command
6142 if "Rolled back to version" in handle:
6143 return main.TRUE
6144 else:
6145 return main.FALSE
6146 except AssertionError:
6147 main.log.exception( "" )
6148 return main.ERROR
6149 except TypeError:
6150 main.log.exception( self.name + ": Object not as expected" )
6151 return main.ERROR
6152 except pexpect.EOF:
6153 main.log.error( self.name + ": EOF exception found" )
6154 main.log.error( self.name + ": " + self.handle.before )
6155 main.cleanAndExit()
6156 except Exception:
6157 main.log.exception( self.name + ": Uncaught exception!" )
6158 main.cleanAndExit()
6159
6160 def issuReset( self ):
6161 """
6162 Resets the In-Service Software Upgrade status after a rollback
6163
6164 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6165 """
6166 try:
6167 cmdStr = "issu reset"
6168 handle = self.sendline( cmdStr )
6169 assert handle is not None, "Error in sendline"
6170 assert "Command not found:" not in handle, handle
6171 assert "Unsupported command:" not in handle, handle
6172 # TODO: Check the version returned by this command
6173 if "Reset version" in handle:
6174 return main.TRUE
6175 else:
6176 return main.FALSE
6177 except AssertionError:
6178 main.log.exception( "" )
6179 return main.ERROR
6180 except TypeError:
6181 main.log.exception( self.name + ": Object not as expected" )
6182 return main.ERROR
6183 except pexpect.EOF:
6184 main.log.error( self.name + ": EOF exception found" )
6185 main.log.error( self.name + ": " + self.handle.before )
6186 main.cleanAndExit()
6187 except Exception:
6188 main.log.exception( self.name + ": Uncaught exception!" )
6189 main.cleanAndExit()
6190
6191 def issuStatus( self ):
6192 """
6193 Status of an In-Service Software Upgrade
6194
6195 Returns the output of the cli command or None on Error
6196 """
6197 try:
6198 cmdStr = "issu status"
6199 handle = self.sendline( cmdStr )
6200 assert handle is not None, "Error in sendline"
6201 assert "Command not found:" not in handle, handle
6202 assert "Unsupported command:" not in handle, handle
6203 return handle
6204 except AssertionError:
6205 main.log.exception( "" )
6206 return None
6207 except TypeError:
6208 main.log.exception( self.name + ": Object not as expected" )
6209 return None
6210 except pexpect.EOF:
6211 main.log.error( self.name + ": EOF exception found" )
6212 main.log.error( self.name + ": " + self.handle.before )
6213 main.cleanAndExit()
6214 except Exception:
6215 main.log.exception( self.name + ": Uncaught exception!" )
6216 main.cleanAndExit()
6217
6218 def issuVersion( self ):
6219 """
6220 Get the version of an In-Service Software Upgrade
6221
6222 Returns the output of the cli command or None on Error
6223 """
6224 try:
6225 cmdStr = "issu version"
6226 handle = self.sendline( cmdStr )
6227 assert handle is not None, "Error in sendline"
6228 assert "Command not found:" not in handle, handle
6229 assert "Unsupported command:" not in handle, handle
6230 return handle
6231 except AssertionError:
6232 main.log.exception( "" )
6233 return None
6234 except TypeError:
6235 main.log.exception( self.name + ": Object not as expected" )
6236 return None
6237 except pexpect.EOF:
6238 main.log.error( self.name + ": EOF exception found" )
6239 main.log.error( self.name + ": " + self.handle.before )
6240 main.cleanAndExit()
6241 except Exception:
6242 main.log.exception( self.name + ": Uncaught exception!" )
6243 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006244
6245 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6246 """
6247 Create a multicast route by calling 'mcast-join' command
6248 sIP: source IP of the multicast route
6249 groupIP: group IP of the multicast route
6250 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6251 dPorts: a list of destination ports of the multicast route
6252 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6253 """
6254 try:
6255 cmdStr = "mcast-join"
6256 cmdStr += " " + str( sIP )
6257 cmdStr += " " + str( groupIP )
6258 cmdStr += " " + str( sPort )
6259 assert isinstance( dPorts, list )
6260 for dPort in dPorts:
6261 cmdStr += " " + str( dPort )
6262 handle = self.sendline( cmdStr )
6263 assert handle is not None, "Error in sendline"
6264 assert "Command not found:" not in handle, handle
6265 assert "Unsupported command:" not in handle, handle
6266 assert "Error executing command" not in handle, handle
6267 if "Added the mcast route" in handle:
6268 return main.TRUE
6269 else:
6270 return main.FALSE
6271 except AssertionError:
6272 main.log.exception( "" )
6273 return None
6274 except TypeError:
6275 main.log.exception( self.name + ": Object not as expected" )
6276 return None
6277 except pexpect.EOF:
6278 main.log.error( self.name + ": EOF exception found" )
6279 main.log.error( self.name + ": " + self.handle.before )
6280 main.cleanAndExit()
6281 except Exception:
6282 main.log.exception( self.name + ": Uncaught exception!" )
6283 main.cleanAndExit()
6284
6285 def mcastDelete( self, sIP, groupIP, dPorts ):
6286 """
6287 Delete a multicast route by calling 'mcast-delete' command
6288 sIP: source IP of the multicast route
6289 groupIP: group IP of the multicast route
6290 dPorts: a list of destination ports of the multicast route
6291 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6292 """
6293 try:
6294 cmdStr = "mcast-delete"
6295 cmdStr += " " + str( sIP )
6296 cmdStr += " " + str( groupIP )
6297 assert isinstance( dPorts, list )
6298 for dPort in dPorts:
6299 cmdStr += " " + str( dPort )
6300 handle = self.sendline( cmdStr )
6301 assert handle is not None, "Error in sendline"
6302 assert "Command not found:" not in handle, handle
6303 assert "Unsupported command:" not in handle, handle
6304 assert "Error executing command" not in handle, handle
6305 if "Updated the mcast route" in handle:
6306 return main.TRUE
6307 else:
6308 return main.FALSE
6309 except AssertionError:
6310 main.log.exception( "" )
6311 return None
6312 except TypeError:
6313 main.log.exception( self.name + ": Object not as expected" )
6314 return None
6315 except pexpect.EOF:
6316 main.log.error( self.name + ": EOF exception found" )
6317 main.log.error( self.name + ": " + self.handle.before )
6318 main.cleanAndExit()
6319 except Exception:
6320 main.log.exception( self.name + ": Uncaught exception!" )
6321 main.cleanAndExit()
6322
6323 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6324 """
6325 Create a multicast route by calling 'mcast-host-join' command
6326 sAddr: we can provide * for ASM or a specific address for SSM
6327 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006328 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006329 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6330 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6331 """
6332 try:
6333 cmdStr = "mcast-host-join"
6334 cmdStr += " -sAddr " + str( sAddr )
6335 cmdStr += " -gAddr " + str( gAddr )
6336 assert isinstance( srcs, list )
6337 for src in srcs:
6338 cmdStr += " -srcs " + str( src )
6339 assert isinstance( sinks, list )
6340 for sink in sinks:
6341 cmdStr += " -sinks " + str( sink )
6342 handle = self.sendline( cmdStr )
6343 assert handle is not None, "Error in sendline"
6344 assert "Command not found:" not in handle, handle
6345 assert "Unsupported command:" not in handle, handle
6346 assert "Error executing command" not in handle, handle
6347 if "Added the mcast route" in handle:
6348 return main.TRUE
6349 else:
6350 return main.FALSE
6351 except AssertionError:
6352 main.log.exception( "" )
6353 return None
6354 except TypeError:
6355 main.log.exception( self.name + ": Object not as expected" )
6356 return None
6357 except pexpect.EOF:
6358 main.log.error( self.name + ": EOF exception found" )
6359 main.log.error( self.name + ": " + self.handle.before )
6360 main.cleanAndExit()
6361 except Exception:
6362 main.log.exception( self.name + ": Uncaught exception!" )
6363 main.cleanAndExit()
6364
6365 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6366 """
6367 Delete multicast sink(s) by calling 'mcast-host-delete' command
6368 sAddr: we can provide * for ASM or a specific address for SSM
6369 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006370 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006371 will delete the route if not specified
6372 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6373 """
6374 try:
6375 cmdStr = "mcast-host-delete"
6376 cmdStr += " -sAddr " + str( sAddr )
6377 cmdStr += " -gAddr " + str( gAddr )
6378 if host:
6379 cmdStr += " -h " + str( host )
6380 handle = self.sendline( cmdStr )
6381 assert handle is not None, "Error in sendline"
6382 assert "Command not found:" not in handle, handle
6383 assert "Unsupported command:" not in handle, handle
6384 assert "Error executing command" not in handle, handle
6385 if "Updated the mcast route" in handle:
6386 return main.TRUE
6387 elif "Deleted the mcast route" in handle:
6388 return main.TRUE
6389 else:
6390 return main.FALSE
6391 except AssertionError:
6392 main.log.exception( "" )
6393 return None
6394 except TypeError:
6395 main.log.exception( self.name + ": Object not as expected" )
6396 return None
6397 except pexpect.EOF:
6398 main.log.error( self.name + ": EOF exception found" )
6399 main.log.error( self.name + ": " + self.handle.before )
6400 main.cleanAndExit()
6401 except Exception:
6402 main.log.exception( self.name + ": Uncaught exception!" )
6403 main.cleanAndExit()
6404
You Wang547893e2018-05-08 13:34:59 -07006405 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6406 """
6407 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6408 sAddr: we can provide * for ASM or a specific address for SSM
6409 gAddr: specifies multicast group address
6410 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6411 will delete the route if not specified
6412 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6413 """
6414 try:
6415 cmdStr = "mcast-sink-delete"
6416 cmdStr += " -sAddr " + str( sAddr )
6417 cmdStr += " -gAddr " + str( gAddr )
6418 if sink:
6419 cmdStr += " -s " + str( sink )
6420 handle = self.sendline( cmdStr )
6421 assert handle is not None, "Error in sendline"
6422 assert "Command not found:" not in handle, handle
6423 assert "Unsupported command:" not in handle, handle
6424 assert "Error executing command" not in handle, handle
6425 if "Updated the mcast route" in handle:
6426 return main.TRUE
6427 elif "Deleted the mcast route" in handle:
6428 return main.TRUE
6429 else:
6430 return main.FALSE
6431 except AssertionError:
6432 main.log.exception( "" )
6433 return None
6434 except TypeError:
6435 main.log.exception( self.name + ": Object not as expected" )
6436 return None
6437 except pexpect.EOF:
6438 main.log.error( self.name + ": EOF exception found" )
6439 main.log.error( self.name + ": " + self.handle.before )
6440 main.cleanAndExit()
6441 except Exception:
6442 main.log.exception( self.name + ": Uncaught exception!" )
6443 main.cleanAndExit()
6444
You Wange24d6272018-03-27 21:18:50 -07006445 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6446 """
6447 Delete multicast src(s) by calling 'mcast-source-delete' command
6448 sAddr: we can provide * for ASM or a specific address for SSM
6449 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006450 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 -07006451 will delete the route if not specified
6452 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6453 """
6454 try:
6455 cmdStr = "mcast-source-delete"
6456 cmdStr += " -sAddr " + str( sAddr )
6457 cmdStr += " -gAddr " + str( gAddr )
6458 if srcs:
6459 assert isinstance( srcs, list )
6460 for src in srcs:
6461 cmdStr += " -src " + str( src )
6462 handle = self.sendline( cmdStr )
6463 assert handle is not None, "Error in sendline"
6464 assert "Command not found:" not in handle, handle
6465 assert "Unsupported command:" not in handle, handle
6466 assert "Error executing command" not in handle, handle
6467 if "Updated the mcast route" in handle:
6468 return main.TRUE
6469 elif "Deleted the mcast route" in handle:
6470 return main.TRUE
6471 else:
6472 return main.FALSE
6473 except AssertionError:
6474 main.log.exception( "" )
6475 return None
6476 except TypeError:
6477 main.log.exception( self.name + ": Object not as expected" )
6478 return None
6479 except pexpect.EOF:
6480 main.log.error( self.name + ": EOF exception found" )
6481 main.log.error( self.name + ": " + self.handle.before )
6482 main.cleanAndExit()
6483 except Exception:
6484 main.log.exception( self.name + ": Uncaught exception!" )
6485 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006486
6487 def netcfg( self, jsonFormat=True, args="" ):
6488 """
6489 Run netcfg cli command with given args
6490 """
6491 try:
6492 cmdStr = "netcfg"
6493 if jsonFormat:
6494 cmdStr = cmdStr + " -j"
6495 if args:
6496 cmdStr = cmdStr + " " + str( args )
6497 handle = self.sendline( cmdStr )
6498 assert handle is not None, "Error in sendline"
6499 assert "Command not found:" not in handle, handle
6500 assert "Unsupported command:" not in handle, handle
6501 assert "Error executing command" not in handle, handle
6502 return handle
6503 except AssertionError:
6504 main.log.exception( "" )
6505 return None
6506 except TypeError:
6507 main.log.exception( self.name + ": Object not as expected" )
6508 return None
6509 except pexpect.EOF:
6510 main.log.error( self.name + ": EOF exception found" )
6511 main.log.error( self.name + ": " + self.handle.before )
6512 main.cleanAndExit()
6513 except Exception:
6514 main.log.exception( self.name + ": Uncaught exception!" )
6515 main.cleanAndExit()
6516
You Wang0fa76e72018-05-18 11:33:25 -07006517 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006518 """
You Wang54b1d672018-06-11 16:44:13 -07006519 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006520 Options:
6521 sAddr: IP address of the source host
6522 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006523 ipv6: True if hosts are IPv6
6524 verbose: return verbose t3 output if True
6525 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006526 """
6527 try:
6528 # Collect information of both hosts from onos
6529 hosts = self.hosts()
6530 hosts = json.loads( hosts )
6531 sHost = None
6532 dHost = None
6533 for host in hosts:
6534 if sAddr in host[ "ipAddresses" ]:
6535 sHost = host
6536 elif dAddr in host[ "ipAddresses" ]:
6537 dHost = host
6538 if sHost and dHost:
6539 break
6540 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006541 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006542 if simple:
6543 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006544 cmdStr = "t3-troubleshoot-simple"
6545 if verbose:
6546 cmdStr += " -vv"
6547 if ipv6:
6548 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006549 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006550 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006551 else:
You Wang54b1d672018-06-11 16:44:13 -07006552 for location in sHost[ "locations" ]:
6553 cmdStr = "t3-troubleshoot"
6554 if verbose:
6555 cmdStr += " -vv"
6556 if ipv6:
6557 cmdStr += " -et ipv6"
6558 cmdStr += " -s " + str( sAddr )
6559 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6560 cmdStr += " -sm " + str( sHost[ "mac" ] )
6561 if sHost[ "vlan" ] != "None":
6562 cmdStr += " -vid " + sHost[ "vlan" ]
6563 cmdStr += " -d " + str( dAddr )
6564 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6565 netcfg = json.loads( netcfg )
6566 assert netcfg, "Failed to get netcfg"
6567 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6568 cmdList.append( cmdStr )
6569 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006570 except AssertionError:
6571 main.log.exception( "" )
6572 return None
6573 except ( KeyError, TypeError ):
6574 main.log.exception( self.name + ": Object not as expected" )
6575 return None
6576 except Exception:
6577 main.log.exception( self.name + ": Uncaught exception!" )
6578 main.cleanAndExit()
6579
6580 def t3( self, sAddr, dAddr, ipv6=False ):
6581 """
You Wang54b1d672018-06-11 16:44:13 -07006582 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006583 Options:
6584 sAddr: IP address of the source host
6585 dAddr: IP address of the destination host
6586 """
6587 try:
You Wang54b1d672018-06-11 16:44:13 -07006588 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6589 assert cmdList is not None, "composeT3Command returned None"
6590 t3Output = ""
6591 for cmdStr in cmdList:
6592 handle = self.sendline( cmdStr )
6593 assert handle is not None, "Error in sendline"
6594 assert "Command not found:" not in handle, handle
6595 assert "Unsupported command:" not in handle, handle
6596 assert "Error executing command" not in handle, handle
6597 assert "Tracing packet" in handle
6598 t3Output += handle
6599 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006600 except AssertionError:
6601 main.log.exception( "" )
6602 return None
6603 except pexpect.EOF:
6604 main.log.error( self.name + ": EOF exception found" )
6605 main.log.error( self.name + ": " + self.handle.before )
6606 main.cleanAndExit()
6607 except Exception:
6608 main.log.exception( self.name + ": Uncaught exception!" )
6609 main.cleanAndExit()