blob: 7aa8a40f9afe3c048fea90a9bcb236dfb537965e [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 )
505 return None
506 except pexpect.EOF:
507 main.log.error( self.name + ": EOF exception found" )
508 main.log.error( self.name + ": " + self.handle.before )
509 if noExit:
510 return None
511 else:
512 main.cleanAndExit()
513 except Exception:
514 main.log.exception( self.name + ": Uncaught exception!" )
515 if noExit:
516 return None
517 else:
518 main.cleanAndExit()
519
520 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False ):
521 """
522 A wrapper around pexpect's sendline/expect. Will return all the output from a given command
523
524 Required Arguments:
525 cmdStr - String to send to the pexpect session
526
527 Optional Arguments:
528 showResponse - Defaults to False. If True will log the response.
529 debug - Defaults to False. If True, will enable debug logging.
530 timeout - Defaults to 10. Amount of time in seconds for a command to return
531 before a timeout.
532 noExit - Defaults to False. If True, will not exit TestON in the event of a
533 closed channel, but instead return None
534
535 Warning: There are no sanity checking to commands sent using this method.
536
537 """
538 try:
539 # Try to reconnect if disconnected from cli
540 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
541 if debug:
542 # NOTE: This adds an average of .4 seconds per call
Jon Hall14a03b52016-05-11 12:07:30 -0700543 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700544 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800545 self.handle.sendline( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -0700546 i = self.handle.expect( "onos>", timeout )
Jon Hall63604932015-02-26 17:09:50 -0800547 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800548 # TODO: do something with i
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000549 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800550 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700551 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700552 main.log.debug( self.name + ": Raw output" )
553 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700554
555 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800556 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800557 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700558 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700559 main.log.debug( self.name + ": ansiEscape output" )
560 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700561
kelvin-onlabfb521662015-02-27 09:52:40 -0800562 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000563 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700564 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700565 main.log.debug( self.name + ": Removed extra returns " +
566 "from output" )
567 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700568
569 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800570 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700571 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700572 main.log.debug( self.name + ": parsed and stripped output" )
573 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700574
Jon Hall63604932015-02-26 17:09:50 -0800575 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700576 output = response.split( cmdStr.strip(), 1 )
Jon Hall0e240372018-05-02 11:21:57 -0700577 if output:
578 if debug:
579 main.log.debug( self.name + ": split output" )
580 for r in output:
581 main.log.debug( self.name + ": " + repr( r ) )
582 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800583 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800584 main.log.info( "Response from ONOS: {}".format( output ) )
Jon Hall0e240372018-05-02 11:21:57 -0700585 self.clearBuffer( debug=debug, timeout=timeout, noExit=noExit )
GlennRC85870432015-11-23 11:45:51 -0800586 return output
GlennRCed771242016-01-13 17:02:47 -0800587 except pexpect.TIMEOUT:
Jon Hall0e240372018-05-02 11:21:57 -0700588 main.log.error( self.name + ": ONOS timeout" )
GlennRCed771242016-01-13 17:02:47 -0800589 if debug:
590 main.log.debug( self.handle.before )
591 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700592 except IndexError:
593 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700594 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700595 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800596 except TypeError:
597 main.log.exception( self.name + ": Object not as expected" )
598 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400599 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800600 main.log.error( self.name + ": EOF exception found" )
601 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700602 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700603 return None
604 else:
Devin Lim44075962017-08-11 10:56:37 -0700605 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800606 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800607 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700608 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700609 return None
610 else:
Devin Lim44075962017-08-11 10:56:37 -0700611 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400612
kelvin8ec71442015-01-15 16:57:00 -0800613 # IMPORTANT NOTE:
614 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800615 # the cli command changing 'a:b' with 'aB'.
616 # Ex ) onos:topology > onosTopology
617 # onos:links > onosLinks
618 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800619
kelvin-onlabd3b64892015-01-20 13:26:24 -0800620 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800621 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400622 Adds a new cluster node by ID and address information.
623 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800624 * nodeId
625 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400626 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800628 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400629 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800630 cmdStr = "add-node " + str( nodeId ) + " " +\
631 str( ONOSIp ) + " " + str( tcpPort )
632 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700633 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800634 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800635 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700636 main.log.error( self.name + ": Error in adding node" )
kelvin8ec71442015-01-15 16:57:00 -0800637 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800638 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400639 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800640 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400641 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800642 except AssertionError:
643 main.log.exception( "" )
644 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800645 except TypeError:
646 main.log.exception( self.name + ": Object not as expected" )
647 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400648 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800649 main.log.error( self.name + ": EOF exception found" )
650 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700651 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800652 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800653 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700654 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400655
kelvin-onlabd3b64892015-01-20 13:26:24 -0800656 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800657 """
andrewonlab86dc3082014-10-13 18:18:38 -0400658 Removes a cluster by ID
659 Issues command: 'remove-node [<node-id>]'
660 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800661 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800662 """
andrewonlab86dc3082014-10-13 18:18:38 -0400663 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400664
kelvin-onlabd3b64892015-01-20 13:26:24 -0800665 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700666 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700667 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800668 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700669 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700670 main.log.error( self.name + ": Error in removing node" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700671 main.log.error( handle )
672 return main.FALSE
673 else:
674 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800675 except AssertionError:
676 main.log.exception( "" )
677 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800678 except TypeError:
679 main.log.exception( self.name + ": Object not as expected" )
680 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400681 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800682 main.log.error( self.name + ": EOF exception found" )
683 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700684 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800685 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800686 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700687 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400688
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700689 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800690 """
andrewonlab7c211572014-10-15 16:45:20 -0400691 List the nodes currently visible
692 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700693 Optional argument:
694 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800695 """
andrewonlab7c211572014-10-15 16:45:20 -0400696 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700697 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700698 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700699 cmdStr += " -j"
700 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700701 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800702 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700703 return output
Jon Hallc6793552016-01-19 14:18:37 -0800704 except AssertionError:
705 main.log.exception( "" )
706 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800707 except TypeError:
708 main.log.exception( self.name + ": Object not as expected" )
709 return None
andrewonlab7c211572014-10-15 16:45:20 -0400710 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800711 main.log.error( self.name + ": EOF exception found" )
712 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700713 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800714 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800715 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700716 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400717
kelvin8ec71442015-01-15 16:57:00 -0800718 def topology( self ):
719 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700720 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700721 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700722 Return:
723 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800724 """
andrewonlab95ce8322014-10-13 14:12:04 -0400725 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700726 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800727 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800728 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800729 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700730 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400731 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800732 except AssertionError:
733 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800734 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800735 except TypeError:
736 main.log.exception( self.name + ": Object not as expected" )
737 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400738 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800739 main.log.error( self.name + ": EOF exception found" )
740 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700741 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800742 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800743 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700744 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800745
jenkins7ead5a82015-03-13 10:28:21 -0700746 def deviceRemove( self, deviceId ):
747 """
748 Removes particular device from storage
749
750 TODO: refactor this function
751 """
752 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700753 cmdStr = "device-remove " + str( deviceId )
754 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800755 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800756 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700757 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700758 main.log.error( self.name + ": Error in removing device" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700759 main.log.error( handle )
760 return main.FALSE
761 else:
762 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800763 except AssertionError:
764 main.log.exception( "" )
765 return None
jenkins7ead5a82015-03-13 10:28:21 -0700766 except TypeError:
767 main.log.exception( self.name + ": Object not as expected" )
768 return None
769 except pexpect.EOF:
770 main.log.error( self.name + ": EOF exception found" )
771 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700772 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700773 except Exception:
774 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700775 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700776
kelvin-onlabd3b64892015-01-20 13:26:24 -0800777 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800778 """
Jon Hall7b02d952014-10-17 20:14:54 -0400779 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400780 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800781 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800782 """
andrewonlab86dc3082014-10-13 18:18:38 -0400783 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700784 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800785 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700786 cmdStr += " -j"
787 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800788 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800789 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700790 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800791 except AssertionError:
792 main.log.exception( "" )
793 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800794 except TypeError:
795 main.log.exception( self.name + ": Object not as expected" )
796 return None
andrewonlab7c211572014-10-15 16:45:20 -0400797 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800798 main.log.error( self.name + ": EOF exception found" )
799 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700800 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800801 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800802 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700803 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400804
kelvin-onlabd3b64892015-01-20 13:26:24 -0800805 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800806 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800807 This balances the devices across all controllers
808 by issuing command: 'onos> onos:balance-masters'
809 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800810 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800811 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800812 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700813 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800814 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800815 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700816 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -0700817 main.log.error( self.name + ": Error in balancing masters" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700818 main.log.error( handle )
819 return main.FALSE
820 else:
821 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800822 except AssertionError:
823 main.log.exception( "" )
824 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800825 except TypeError:
826 main.log.exception( self.name + ": Object not as expected" )
827 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800828 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800829 main.log.error( self.name + ": EOF exception found" )
830 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700831 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800832 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800833 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700834 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800835
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000836 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700837 """
838 Returns the output of the masters command.
839 Optional argument:
840 * jsonFormat - boolean indicating if you want output in json
841 """
842 try:
843 cmdStr = "onos:masters"
844 if jsonFormat:
845 cmdStr += " -j"
846 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700847 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800848 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700849 return output
Jon Hallc6793552016-01-19 14:18:37 -0800850 except AssertionError:
851 main.log.exception( "" )
852 return None
acsmars24950022015-07-30 18:00:43 -0700853 except TypeError:
854 main.log.exception( self.name + ": Object not as expected" )
855 return None
856 except pexpect.EOF:
857 main.log.error( self.name + ": EOF exception found" )
858 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700859 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700860 except Exception:
861 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700862 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700863
Jon Hallc6793552016-01-19 14:18:37 -0800864 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700865 """
866 Uses the master command to check that the devices' leadership
867 is evenly divided
868
869 Dependencies: checkMasters() and summary()
870
Jon Hall6509dbf2016-06-21 17:01:17 -0700871 Returns main.TRUE if the devices are balanced
872 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700873 Exits on Exception
874 Returns None on TypeError
875 """
876 try:
Jon Hallc6793552016-01-19 14:18:37 -0800877 summaryOutput = self.summary()
878 totalDevices = json.loads( summaryOutput )[ "devices" ]
879 except ( TypeError, ValueError ):
880 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
881 return None
882 try:
acsmars24950022015-07-30 18:00:43 -0700883 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800884 mastersOutput = self.checkMasters()
885 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700886 first = masters[ 0 ][ "size" ]
887 for master in masters:
888 totalOwnedDevices += master[ "size" ]
889 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
890 main.log.error( "Mastership not balanced" )
891 main.log.info( "\n" + self.checkMasters( False ) )
892 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700893 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700894 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700895 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800896 except ( TypeError, ValueError ):
897 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700898 return None
899 except pexpect.EOF:
900 main.log.error( self.name + ": EOF exception found" )
901 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700902 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700903 except Exception:
904 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700905 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700906
YPZhangfebf7302016-05-24 16:45:56 -0700907 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800908 """
Jon Halle8217482014-10-17 13:49:14 -0400909 Lists all core links
910 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800911 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800912 """
Jon Halle8217482014-10-17 13:49:14 -0400913 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700914 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800915 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700916 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700917 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800918 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800919 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700920 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800921 except AssertionError:
922 main.log.exception( "" )
923 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800924 except TypeError:
925 main.log.exception( self.name + ": Object not as expected" )
926 return None
Jon Halle8217482014-10-17 13:49:14 -0400927 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800928 main.log.error( self.name + ": EOF exception found" )
929 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700930 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800931 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800932 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700933 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400934
kelvin-onlabd3b64892015-01-20 13:26:24 -0800935 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800936 """
Jon Halle8217482014-10-17 13:49:14 -0400937 Lists all ports
938 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800939 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800940 """
Jon Halle8217482014-10-17 13:49:14 -0400941 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700942 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800943 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700944 cmdStr += " -j"
945 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800946 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800947 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700948 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800949 except AssertionError:
950 main.log.exception( "" )
951 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800952 except TypeError:
953 main.log.exception( self.name + ": Object not as expected" )
954 return None
Jon Halle8217482014-10-17 13:49:14 -0400955 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800956 main.log.error( self.name + ": EOF exception found" )
957 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700958 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800959 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800960 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700961 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400962
kelvin-onlabd3b64892015-01-20 13:26:24 -0800963 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800964 """
Jon Hall983a1702014-10-28 18:44:22 -0400965 Lists all devices and the controllers with roles assigned to them
966 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800967 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800968 """
andrewonlab7c211572014-10-15 16:45:20 -0400969 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700970 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700972 cmdStr += " -j"
973 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800974 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800975 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700976 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800977 except AssertionError:
978 main.log.exception( "" )
979 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800980 except TypeError:
981 main.log.exception( self.name + ": Object not as expected" )
982 return None
Jon Hall983a1702014-10-28 18:44:22 -0400983 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800984 main.log.error( self.name + ": EOF exception found" )
985 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700986 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800987 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800988 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700989 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -0400990
kelvin-onlabd3b64892015-01-20 13:26:24 -0800991 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800992 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800993 Given the a string containing the json representation of the "roles"
994 cli command and a partial or whole device id, returns a json object
995 containing the roles output for the first device whose id contains
996 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400997
998 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800999 A dict of the role assignments for the given device or
1000 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001001 """
Jon Hall983a1702014-10-28 18:44:22 -04001002 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001003 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001004 return None
1005 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001006 rawRoles = self.roles()
1007 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001008 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001009 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001010 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001011 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001012 return device
1013 return None
Jon Hallc6793552016-01-19 14:18:37 -08001014 except ( TypeError, ValueError ):
1015 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001016 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001017 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001018 main.log.error( self.name + ": EOF exception found" )
1019 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001020 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001021 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001022 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001023 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001024
kelvin-onlabd3b64892015-01-20 13:26:24 -08001025 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001026 """
Jon Hall94fd0472014-12-08 11:52:42 -08001027 Iterates through each device and checks if there is a master assigned
1028 Returns: main.TRUE if each device has a master
1029 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001030 """
Jon Hall94fd0472014-12-08 11:52:42 -08001031 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001032 rawRoles = self.roles()
1033 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001034 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001035 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001036 # print device
1037 if device[ 'master' ] == "none":
1038 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001039 return main.FALSE
1040 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001041 except ( TypeError, ValueError ):
1042 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001043 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001044 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001045 main.log.error( self.name + ": EOF exception found" )
1046 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001047 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001048 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001049 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001050 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001051
kelvin-onlabd3b64892015-01-20 13:26:24 -08001052 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001053 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001054 Returns string of paths, and the cost.
1055 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001056 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001057 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001058 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1059 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001060 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001061 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001062 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001063 main.log.error( self.name + ": Error in getting paths" )
kelvin8ec71442015-01-15 16:57:00 -08001064 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001065 else:
kelvin8ec71442015-01-15 16:57:00 -08001066 path = handle.split( ";" )[ 0 ]
1067 cost = handle.split( ";" )[ 1 ]
1068 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001069 except AssertionError:
1070 main.log.exception( "" )
1071 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001072 except TypeError:
1073 main.log.exception( self.name + ": Object not as expected" )
1074 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001075 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001076 main.log.error( self.name + ": EOF exception found" )
1077 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001078 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001079 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001080 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001081 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001082
kelvin-onlabd3b64892015-01-20 13:26:24 -08001083 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001084 """
Jon Hallffb386d2014-11-21 13:43:38 -08001085 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001086 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001087 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001088 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001089 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001090 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001091 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001092 cmdStr += " -j"
1093 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001094 if handle:
1095 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001096 # TODO: Maybe make this less hardcoded
1097 # ConsistentMap Exceptions
1098 assert "org.onosproject.store.service" not in handle
1099 # Node not leader
1100 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001101 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001102 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07001103 main.log.exception( self.name + ": Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001104 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001105 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001106 except TypeError:
1107 main.log.exception( self.name + ": Object not as expected" )
1108 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001109 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001110 main.log.error( self.name + ": EOF exception found" )
1111 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001112 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001113 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001114 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001115 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001116
kelvin-onlabd3b64892015-01-20 13:26:24 -08001117 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001118 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001119 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001120
Jon Hallefbd9792015-03-05 16:11:36 -08001121 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001122 partial mac address
1123
Jon Hall42db6dc2014-10-24 19:03:48 -04001124 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001125 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001126 try:
kelvin8ec71442015-01-15 16:57:00 -08001127 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001128 return None
1129 else:
1130 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001131 rawHosts = self.hosts()
1132 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001133 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001135 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001136 if not host:
1137 pass
1138 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001139 return host
1140 return None
Jon Hallc6793552016-01-19 14:18:37 -08001141 except ( TypeError, ValueError ):
1142 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001143 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001144 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001145 main.log.error( self.name + ": EOF exception found" )
1146 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001147 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001148 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001149 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001150 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001151
kelvin-onlabd3b64892015-01-20 13:26:24 -08001152 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001153 """
1154 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001155 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001156
andrewonlab3f0a4af2014-10-17 12:25:14 -04001157 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001158 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001159 IMPORTANT:
1160 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001161 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001162 Furthermore, it assumes that value of VLAN is '-1'
1163 Description:
kelvin8ec71442015-01-15 16:57:00 -08001164 Converts mininet hosts ( h1, h2, h3... ) into
1165 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1166 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001167 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001168 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001169
kelvin-onlabd3b64892015-01-20 13:26:24 -08001170 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001171 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001172 hostHex = hex( int( host ) ).zfill( 12 )
1173 hostHex = str( hostHex ).replace( 'x', '0' )
1174 i = iter( str( hostHex ) )
1175 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1176 hostHex = hostHex + "/-1"
1177 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001178
kelvin-onlabd3b64892015-01-20 13:26:24 -08001179 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001180
Jon Halld4d4b372015-01-28 16:02:41 -08001181 except TypeError:
1182 main.log.exception( self.name + ": Object not as expected" )
1183 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001184 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001185 main.log.error( self.name + ": EOF exception found" )
1186 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001187 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001188 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001189 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001190 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001191
You Wangbc898b82018-05-03 16:22:34 -07001192 def verifyHostLocation( self, hostIp, location ):
1193 """
1194 Description:
1195 Verify the host given is discovered in all locations expected
1196 Required:
1197 hostIp: IP address of the host
1198 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1199 Could be a string or list
1200 Returns:
1201 main.TRUE if host is discovered on all locations provided
1202 main.FALSE otherwise
1203 """
1204 import json
1205 locations = [ location ] if isinstance( location, str ) else location
1206 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1207 try:
1208 hosts = self.hosts()
1209 hosts = json.loads( hosts )
1210 targetHost = None
1211 for host in hosts:
1212 if hostIp in host[ "ipAddresses" ]:
1213 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001214 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001215 result = main.TRUE
1216 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1217 for loc in locations:
1218 discovered = False
1219 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001220 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1221 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001222 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001223 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001224 break
1225 if discovered:
1226 locationsDiscovered.remove( locDiscovered )
1227 else:
1228 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1229 result = main.FALSE
1230 if locationsDiscovered:
1231 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1232 result = main.FALSE
1233 return result
1234 except KeyError:
1235 main.log.exception( self.name + ": host data not as expected: " + hosts )
1236 return None
1237 except pexpect.EOF:
1238 main.log.error( self.name + ": EOF exception found" )
1239 main.log.error( self.name + ": " + self.handle.before )
1240 main.cleanAndExit()
1241 except Exception:
1242 main.log.exception( self.name + ": Uncaught exception" )
1243 return None
1244
You Wang53dba1e2018-02-02 17:45:44 -08001245 def verifyHostIp( self, hostList=[], prefix="" ):
1246 """
1247 Description:
1248 Verify that all hosts have IP address assigned to them
1249 Optional:
1250 hostList: If specified, verifications only happen to the hosts
1251 in hostList
1252 prefix: at least one of the ip address assigned to the host
1253 needs to have the specified prefix
1254 Returns:
1255 main.TRUE if all hosts have specific IP address assigned;
1256 main.FALSE otherwise
1257 """
1258 import json
1259 try:
1260 hosts = self.hosts()
1261 hosts = json.loads( hosts )
1262 if not hostList:
1263 hostList = [ host[ "id" ] for host in hosts ]
1264 for host in hosts:
1265 hostId = host[ "id" ]
1266 if hostId not in hostList:
1267 continue
1268 ipList = host[ "ipAddresses" ]
1269 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1270 if not ipList:
1271 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1272 else:
1273 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1274 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1275 else:
1276 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1277 hostList.remove( hostId )
1278 if hostList:
1279 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1280 return main.FALSE
1281 else:
1282 return main.TRUE
1283 except KeyError:
1284 main.log.exception( self.name + ": host data not as expected: " + hosts )
1285 return None
1286 except pexpect.EOF:
1287 main.log.error( self.name + ": EOF exception found" )
1288 main.log.error( self.name + ": " + self.handle.before )
1289 main.cleanAndExit()
1290 except Exception:
1291 main.log.exception( self.name + ": Uncaught exception" )
1292 return None
1293
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001294 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001295 """
andrewonlabe6745342014-10-17 14:29:13 -04001296 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001297 * hostIdOne: ONOS host id for host1
1298 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001299 Optional:
1300 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001301 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001302 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001303 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001304 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001305 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001306 Returns:
1307 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001308 """
andrewonlabe6745342014-10-17 14:29:13 -04001309 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001310 cmdStr = "add-host-intent "
1311 if vlanId:
1312 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001313 if setVlan:
1314 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001315 if encap:
1316 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001317 if bandwidth:
1318 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001319 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001320 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001321 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001322 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001323 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001324 main.log.error( self.name + ": Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001325 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001326 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001327 else:
1328 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001329 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001330 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001331 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001332 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001333 else:
1334 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001335 main.log.debug( "Response from ONOS was: " +
1336 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001337 return None
Jon Hallc6793552016-01-19 14:18:37 -08001338 except AssertionError:
1339 main.log.exception( "" )
1340 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001341 except TypeError:
1342 main.log.exception( self.name + ": Object not as expected" )
1343 return None
andrewonlabe6745342014-10-17 14:29:13 -04001344 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001345 main.log.error( self.name + ": EOF exception found" )
1346 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001347 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001348 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001349 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001350 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001351
kelvin-onlabd3b64892015-01-20 13:26:24 -08001352 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001353 """
andrewonlab7b31d232014-10-24 13:31:47 -04001354 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001355 * ingressDevice: device id of ingress device
1356 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001357 Optional:
1358 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001359 Description:
1360 Adds an optical intent by specifying an ingress and egress device
1361 Returns:
1362 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001363 """
andrewonlab7b31d232014-10-24 13:31:47 -04001364 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001365 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1366 " " + str( egressDevice )
1367 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001368 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001369 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001370 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001371 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001372 main.log.error( self.name + ": Error in adding Optical intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001373 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001374 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001375 main.log.info( "Optical intent installed between " +
1376 str( ingressDevice ) + " and " +
1377 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001378 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001379 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001380 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001381 else:
1382 main.log.error( "Error, intent ID not found" )
1383 return None
Jon Hallc6793552016-01-19 14:18:37 -08001384 except AssertionError:
1385 main.log.exception( "" )
1386 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001387 except TypeError:
1388 main.log.exception( self.name + ": Object not as expected" )
1389 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001390 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001391 main.log.error( self.name + ": EOF exception found" )
1392 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001393 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001394 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001395 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001396 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001397
kelvin-onlabd3b64892015-01-20 13:26:24 -08001398 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001399 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001400 ingressDevice,
1401 egressDevice,
1402 portIngress="",
1403 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001404 ethType="",
1405 ethSrc="",
1406 ethDst="",
1407 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001408 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001409 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001410 ipProto="",
1411 ipSrc="",
1412 ipDst="",
1413 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001414 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001415 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001416 setVlan="",
1417 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001418 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001419 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001420 * ingressDevice: device id of ingress device
1421 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001422 Optional:
1423 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001424 * ethSrc: specify ethSrc ( i.e. src mac addr )
1425 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001426 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001427 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001428 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001429 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001430 * ipSrc: specify ip source address
1431 * ipDst: specify ip destination address
1432 * tcpSrc: specify tcp source port
1433 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001434 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001435 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001436 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001437 Description:
kelvin8ec71442015-01-15 16:57:00 -08001438 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001439 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001440 Returns:
1441 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001442
Jon Halle3f39ff2015-01-13 11:50:53 -08001443 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001444 options developers provide for point-to-point
1445 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001446 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001447 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001448 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001449
Jeremy Songsterff553672016-05-12 17:06:23 -07001450 if ethType:
1451 cmd += " --ethType " + str( ethType )
1452 if ethSrc:
1453 cmd += " --ethSrc " + str( ethSrc )
1454 if ethDst:
1455 cmd += " --ethDst " + str( ethDst )
1456 if bandwidth:
1457 cmd += " --bandwidth " + str( bandwidth )
1458 if lambdaAlloc:
1459 cmd += " --lambda "
1460 if ipProto:
1461 cmd += " --ipProto " + str( ipProto )
1462 if ipSrc:
1463 cmd += " --ipSrc " + str( ipSrc )
1464 if ipDst:
1465 cmd += " --ipDst " + str( ipDst )
1466 if tcpSrc:
1467 cmd += " --tcpSrc " + str( tcpSrc )
1468 if tcpDst:
1469 cmd += " --tcpDst " + str( tcpDst )
1470 if vlanId:
1471 cmd += " -v " + str( vlanId )
1472 if setVlan:
1473 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001474 if encap:
1475 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001476 if protected:
1477 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001478
kelvin8ec71442015-01-15 16:57:00 -08001479 # Check whether the user appended the port
1480 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001481 if "/" in ingressDevice:
1482 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001483 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001484 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001485 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001486 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001487 # Would it make sense to throw an exception and exit
1488 # the test?
1489 return None
andrewonlab36af3822014-11-18 17:48:18 -05001490
kelvin8ec71442015-01-15 16:57:00 -08001491 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001492 str( ingressDevice ) + "/" +\
1493 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001494
kelvin-onlabd3b64892015-01-20 13:26:24 -08001495 if "/" in egressDevice:
1496 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001497 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001498 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001499 main.log.error( "You must specify the egress port" )
1500 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001501
kelvin8ec71442015-01-15 16:57:00 -08001502 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001503 str( egressDevice ) + "/" +\
1504 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001505
kelvin-onlab898a6c62015-01-16 14:13:53 -08001506 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001507 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001508 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001509 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001510 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001511 main.log.error( self.name + ": Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001512 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001513 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001514 # TODO: print out all the options in this message?
1515 main.log.info( "Point-to-point intent installed between " +
1516 str( ingressDevice ) + " and " +
1517 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001518 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001519 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001520 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001521 else:
1522 main.log.error( "Error, intent ID not found" )
1523 return None
Jon Hallc6793552016-01-19 14:18:37 -08001524 except AssertionError:
1525 main.log.exception( "" )
1526 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001527 except TypeError:
1528 main.log.exception( self.name + ": Object not as expected" )
1529 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001530 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001531 main.log.error( self.name + ": EOF exception found" )
1532 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001533 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001534 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001535 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001536 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001537
kelvin-onlabd3b64892015-01-20 13:26:24 -08001538 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001539 self,
shahshreyac2f97072015-03-19 17:04:29 -07001540 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001541 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001542 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001543 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001544 ethType="",
1545 ethSrc="",
1546 ethDst="",
1547 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001548 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001549 ipProto="",
1550 ipSrc="",
1551 ipDst="",
1552 tcpSrc="",
1553 tcpDst="",
1554 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001555 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001556 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001557 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001558 partial=False,
1559 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001560 """
shahshreyad0c80432014-12-04 16:56:05 -08001561 Note:
shahshreya70622b12015-03-19 17:19:00 -07001562 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001563 is same. That is, all ingress devices include port numbers
1564 with a "/" or all ingress devices could specify device
1565 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001566 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001567 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001568 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001569 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001570 Optional:
1571 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001572 * ethSrc: specify ethSrc ( i.e. src mac addr )
1573 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001574 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001575 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001576 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001577 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001578 * ipSrc: specify ip source address
1579 * ipDst: specify ip destination address
1580 * tcpSrc: specify tcp source port
1581 * tcpDst: specify tcp destination port
1582 * setEthSrc: action to Rewrite Source MAC Address
1583 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001584 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001585 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001586 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001587 Description:
kelvin8ec71442015-01-15 16:57:00 -08001588 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001589 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001590 Returns:
1591 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001592
Jon Halle3f39ff2015-01-13 11:50:53 -08001593 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001594 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001595 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001596 """
shahshreyad0c80432014-12-04 16:56:05 -08001597 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001598 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001599
Jeremy Songsterff553672016-05-12 17:06:23 -07001600 if ethType:
1601 cmd += " --ethType " + str( ethType )
1602 if ethSrc:
1603 cmd += " --ethSrc " + str( ethSrc )
1604 if ethDst:
1605 cmd += " --ethDst " + str( ethDst )
1606 if bandwidth:
1607 cmd += " --bandwidth " + str( bandwidth )
1608 if lambdaAlloc:
1609 cmd += " --lambda "
1610 if ipProto:
1611 cmd += " --ipProto " + str( ipProto )
1612 if ipSrc:
1613 cmd += " --ipSrc " + str( ipSrc )
1614 if ipDst:
1615 cmd += " --ipDst " + str( ipDst )
1616 if tcpSrc:
1617 cmd += " --tcpSrc " + str( tcpSrc )
1618 if tcpDst:
1619 cmd += " --tcpDst " + str( tcpDst )
1620 if setEthSrc:
1621 cmd += " --setEthSrc " + str( setEthSrc )
1622 if setEthDst:
1623 cmd += " --setEthDst " + str( setEthDst )
1624 if vlanId:
1625 cmd += " -v " + str( vlanId )
1626 if setVlan:
1627 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001628 if partial:
1629 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001630 if encap:
1631 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001632
kelvin8ec71442015-01-15 16:57:00 -08001633 # Check whether the user appended the port
1634 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001635
1636 if portIngressList is None:
1637 for ingressDevice in ingressDeviceList:
1638 if "/" in ingressDevice:
1639 cmd += " " + str( ingressDevice )
1640 else:
1641 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001642 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001643 # TODO: perhaps more meaningful return
1644 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001645 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001646 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001647 for ingressDevice, portIngress in zip( ingressDeviceList,
1648 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001649 cmd += " " + \
1650 str( ingressDevice ) + "/" +\
1651 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001652 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001653 main.log.error( "Device list and port list does not " +
1654 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001655 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001656 if "/" in egressDevice:
1657 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001658 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001659 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001660 main.log.error( "You must specify " +
1661 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001662 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001663
kelvin8ec71442015-01-15 16:57:00 -08001664 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001665 str( egressDevice ) + "/" +\
1666 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001667 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001668 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001669 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001670 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001671 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001672 main.log.error( self.name + ": Error in adding multipoint-to-singlepoint " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001673 "intent" )
1674 return None
shahshreyad0c80432014-12-04 16:56:05 -08001675 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001676 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001677 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001678 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001679 else:
1680 main.log.error( "Error, intent ID not found" )
1681 return None
Jon Hallc6793552016-01-19 14:18:37 -08001682 except AssertionError:
1683 main.log.exception( "" )
1684 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001685 except TypeError:
1686 main.log.exception( self.name + ": Object not as expected" )
1687 return None
1688 except pexpect.EOF:
1689 main.log.error( self.name + ": EOF exception found" )
1690 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001691 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001692 except Exception:
1693 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001694 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001695
1696 def addSinglepointToMultipointIntent(
1697 self,
1698 ingressDevice,
1699 egressDeviceList,
1700 portIngress="",
1701 portEgressList=None,
1702 ethType="",
1703 ethSrc="",
1704 ethDst="",
1705 bandwidth="",
1706 lambdaAlloc=False,
1707 ipProto="",
1708 ipSrc="",
1709 ipDst="",
1710 tcpSrc="",
1711 tcpDst="",
1712 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001713 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001714 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001715 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001716 partial=False,
1717 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001718 """
1719 Note:
1720 This function assumes the format of all egress devices
1721 is same. That is, all egress devices include port numbers
1722 with a "/" or all egress devices could specify device
1723 ids and port numbers seperately.
1724 Required:
1725 * EgressDeviceList: List of device ids of egress device
1726 ( Atleast 2 eress devices required in the list )
1727 * ingressDevice: device id of ingress device
1728 Optional:
1729 * ethType: specify ethType
1730 * ethSrc: specify ethSrc ( i.e. src mac addr )
1731 * ethDst: specify ethDst ( i.e. dst mac addr )
1732 * bandwidth: specify bandwidth capacity of link
1733 * lambdaAlloc: if True, intent will allocate lambda
1734 for the specified intent
1735 * ipProto: specify ip protocol
1736 * ipSrc: specify ip source address
1737 * ipDst: specify ip destination address
1738 * tcpSrc: specify tcp source port
1739 * tcpDst: specify tcp destination port
1740 * setEthSrc: action to Rewrite Source MAC Address
1741 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001742 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001743 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001744 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001745 Description:
1746 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1747 specifying device id's and optional fields
1748 Returns:
1749 A string of the intent id or None on error
1750
1751 NOTE: This function may change depending on the
1752 options developers provide for singlepoint-to-multipoint
1753 intent via cli
1754 """
1755 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001756 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001757
Jeremy Songsterff553672016-05-12 17:06:23 -07001758 if ethType:
1759 cmd += " --ethType " + str( ethType )
1760 if ethSrc:
1761 cmd += " --ethSrc " + str( ethSrc )
1762 if ethDst:
1763 cmd += " --ethDst " + str( ethDst )
1764 if bandwidth:
1765 cmd += " --bandwidth " + str( bandwidth )
1766 if lambdaAlloc:
1767 cmd += " --lambda "
1768 if ipProto:
1769 cmd += " --ipProto " + str( ipProto )
1770 if ipSrc:
1771 cmd += " --ipSrc " + str( ipSrc )
1772 if ipDst:
1773 cmd += " --ipDst " + str( ipDst )
1774 if tcpSrc:
1775 cmd += " --tcpSrc " + str( tcpSrc )
1776 if tcpDst:
1777 cmd += " --tcpDst " + str( tcpDst )
1778 if setEthSrc:
1779 cmd += " --setEthSrc " + str( setEthSrc )
1780 if setEthDst:
1781 cmd += " --setEthDst " + str( setEthDst )
1782 if vlanId:
1783 cmd += " -v " + str( vlanId )
1784 if setVlan:
1785 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001786 if partial:
1787 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001788 if encap:
1789 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001790
1791 # Check whether the user appended the port
1792 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001793
kelvin-onlabb9408212015-04-01 13:34:04 -07001794 if "/" in ingressDevice:
1795 cmd += " " + str( ingressDevice )
1796 else:
1797 if not portIngress:
1798 main.log.error( "You must specify " +
1799 "the Ingress port" )
1800 return main.FALSE
1801
1802 cmd += " " +\
1803 str( ingressDevice ) + "/" +\
1804 str( portIngress )
1805
1806 if portEgressList is None:
1807 for egressDevice in egressDeviceList:
1808 if "/" in egressDevice:
1809 cmd += " " + str( egressDevice )
1810 else:
1811 main.log.error( "You must specify " +
1812 "the egress port" )
1813 # TODO: perhaps more meaningful return
1814 return main.FALSE
1815 else:
1816 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001817 for egressDevice, portEgress in zip( egressDeviceList,
1818 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001819 cmd += " " + \
1820 str( egressDevice ) + "/" +\
1821 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001822 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001823 main.log.error( "Device list and port list does not " +
1824 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001825 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001826 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001827 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001828 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001829 # If error, return error message
1830 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001831 main.log.error( self.name + ": Error in adding singlepoint-to-multipoint " +
kelvin-onlabb9408212015-04-01 13:34:04 -07001832 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001833 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001834 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001835 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001836 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001837 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001838 else:
1839 main.log.error( "Error, intent ID not found" )
1840 return None
Jon Hallc6793552016-01-19 14:18:37 -08001841 except AssertionError:
1842 main.log.exception( "" )
1843 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001844 except TypeError:
1845 main.log.exception( self.name + ": Object not as expected" )
1846 return None
shahshreyad0c80432014-12-04 16:56:05 -08001847 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001848 main.log.error( self.name + ": EOF exception found" )
1849 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001850 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001851 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001852 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001853 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001854
Hari Krishna9e232602015-04-13 17:29:08 -07001855 def addMplsIntent(
1856 self,
1857 ingressDevice,
1858 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001859 ingressPort="",
1860 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001861 ethType="",
1862 ethSrc="",
1863 ethDst="",
1864 bandwidth="",
1865 lambdaAlloc=False,
1866 ipProto="",
1867 ipSrc="",
1868 ipDst="",
1869 tcpSrc="",
1870 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001871 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001872 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001873 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001874 """
1875 Required:
1876 * ingressDevice: device id of ingress device
1877 * egressDevice: device id of egress device
1878 Optional:
1879 * ethType: specify ethType
1880 * ethSrc: specify ethSrc ( i.e. src mac addr )
1881 * ethDst: specify ethDst ( i.e. dst mac addr )
1882 * bandwidth: specify bandwidth capacity of link
1883 * lambdaAlloc: if True, intent will allocate lambda
1884 for the specified intent
1885 * ipProto: specify ip protocol
1886 * ipSrc: specify ip source address
1887 * ipDst: specify ip destination address
1888 * tcpSrc: specify tcp source port
1889 * tcpDst: specify tcp destination port
1890 * ingressLabel: Ingress MPLS label
1891 * egressLabel: Egress MPLS label
1892 Description:
1893 Adds MPLS intent by
1894 specifying device id's and optional fields
1895 Returns:
1896 A string of the intent id or None on error
1897
1898 NOTE: This function may change depending on the
1899 options developers provide for MPLS
1900 intent via cli
1901 """
1902 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001903 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001904
Jeremy Songsterff553672016-05-12 17:06:23 -07001905 if ethType:
1906 cmd += " --ethType " + str( ethType )
1907 if ethSrc:
1908 cmd += " --ethSrc " + str( ethSrc )
1909 if ethDst:
1910 cmd += " --ethDst " + str( ethDst )
1911 if bandwidth:
1912 cmd += " --bandwidth " + str( bandwidth )
1913 if lambdaAlloc:
1914 cmd += " --lambda "
1915 if ipProto:
1916 cmd += " --ipProto " + str( ipProto )
1917 if ipSrc:
1918 cmd += " --ipSrc " + str( ipSrc )
1919 if ipDst:
1920 cmd += " --ipDst " + str( ipDst )
1921 if tcpSrc:
1922 cmd += " --tcpSrc " + str( tcpSrc )
1923 if tcpDst:
1924 cmd += " --tcpDst " + str( tcpDst )
1925 if ingressLabel:
1926 cmd += " --ingressLabel " + str( ingressLabel )
1927 if egressLabel:
1928 cmd += " --egressLabel " + str( egressLabel )
1929 if priority:
1930 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001931
1932 # Check whether the user appended the port
1933 # or provided it as an input
1934 if "/" in ingressDevice:
1935 cmd += " " + str( ingressDevice )
1936 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001937 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001938 main.log.error( "You must specify the ingress port" )
1939 return None
1940
1941 cmd += " " + \
1942 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001943 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001944
1945 if "/" in egressDevice:
1946 cmd += " " + str( egressDevice )
1947 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001948 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001949 main.log.error( "You must specify the egress port" )
1950 return None
1951
1952 cmd += " " +\
1953 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001954 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001955
1956 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001957 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001958 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001959 # If error, return error message
1960 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07001961 main.log.error( self.name + ": Error in adding mpls intent" )
Hari Krishna9e232602015-04-13 17:29:08 -07001962 return None
1963 else:
1964 # TODO: print out all the options in this message?
1965 main.log.info( "MPLS intent installed between " +
1966 str( ingressDevice ) + " and " +
1967 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001968 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07001969 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001970 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07001971 else:
1972 main.log.error( "Error, intent ID not found" )
1973 return None
Jon Hallc6793552016-01-19 14:18:37 -08001974 except AssertionError:
1975 main.log.exception( "" )
1976 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001977 except TypeError:
1978 main.log.exception( self.name + ": Object not as expected" )
1979 return None
1980 except pexpect.EOF:
1981 main.log.error( self.name + ": EOF exception found" )
1982 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001983 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001984 except Exception:
1985 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001986 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001987
Jon Hallefbd9792015-03-05 16:11:36 -08001988 def removeIntent( self, intentId, app='org.onosproject.cli',
1989 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001990 """
shahshreya1c818fc2015-02-26 13:44:08 -08001991 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001992 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001993 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001994 -p or --purge: Purge the intent from the store after removal
1995
Jon Halle3f39ff2015-01-13 11:50:53 -08001996 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001997 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001998 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001999 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002000 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002001 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08002002 if purge:
2003 cmdStr += " -p"
2004 if sync:
2005 cmdStr += " -s"
2006
2007 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002008 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002009 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002010 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08002011 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002012 main.log.error( self.name + ": Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08002013 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04002014 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08002015 # TODO: Should this be main.TRUE
2016 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002017 except AssertionError:
2018 main.log.exception( "" )
2019 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002020 except TypeError:
2021 main.log.exception( self.name + ": Object not as expected" )
2022 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002023 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002024 main.log.error( self.name + ": EOF exception found" )
2025 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002026 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002027 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002028 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002029 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002030
YPZhangfebf7302016-05-24 16:45:56 -07002031 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08002032 """
2033 Description:
2034 Remove all the intents
2035 Optional args:-
2036 -s or --sync: Waits for the removal before returning
2037 -p or --purge: Purge the intent from the store after removal
2038 Returns:
2039 Returns main.TRUE if all intents are removed, otherwise returns
2040 main.FALSE; Returns None for exception
2041 """
2042 try:
2043 cmdStr = "remove-intent"
2044 if purge:
2045 cmdStr += " -p"
2046 if sync:
2047 cmdStr += " -s"
2048
2049 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002050 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002051 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002052 assert "Command not found:" not in handle, handle
2053 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002054 main.log.error( self.name + ": Error in removing intent" )
Jeremy42df2e72016-02-23 16:37:46 -08002055 return main.FALSE
2056 else:
2057 return main.TRUE
2058 except AssertionError:
2059 main.log.exception( "" )
2060 return None
2061 except TypeError:
2062 main.log.exception( self.name + ": Object not as expected" )
2063 return None
2064 except pexpect.EOF:
2065 main.log.error( self.name + ": EOF exception found" )
2066 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002067 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002068 except Exception:
2069 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002070 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002071
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002072 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002073 """
2074 Purges all WITHDRAWN Intents
2075 """
2076 try:
2077 cmdStr = "purge-intents"
2078 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002079 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002080 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002081 if re.search( "Error", handle ):
Jon Hall0e240372018-05-02 11:21:57 -07002082 main.log.error( self.name + ": Error in purging intents" )
Hari Krishna0ce0e152015-06-23 09:55:29 -07002083 return main.FALSE
2084 else:
2085 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002086 except AssertionError:
2087 main.log.exception( "" )
2088 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002089 except TypeError:
2090 main.log.exception( self.name + ": Object not as expected" )
2091 return None
2092 except pexpect.EOF:
2093 main.log.error( self.name + ": EOF exception found" )
2094 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002095 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002096 except Exception:
2097 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002098 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002099
Devin Lime6fe3c42017-10-18 16:28:40 -07002100 def wipeout( self ):
2101 """
2102 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2103 """
2104 try:
2105 cmdStr = "wipe-out please"
2106 handle = self.sendline( cmdStr, timeout=60 )
2107 assert handle is not None, "Error in sendline"
2108 assert "Command not found:" not in handle, handle
2109 return main.TRUE
2110 except AssertionError:
2111 main.log.exception( "" )
2112 return None
2113 except TypeError:
2114 main.log.exception( self.name + ": Object not as expected" )
2115 return None
2116 except pexpect.EOF:
2117 main.log.error( self.name + ": EOF exception found" )
2118 main.log.error( self.name + ": " + self.handle.before )
2119 main.cleanAndExit()
2120 except Exception:
2121 main.log.exception( self.name + ": Uncaught exception!" )
2122 main.cleanAndExit()
2123
kelvin-onlabd3b64892015-01-20 13:26:24 -08002124 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002125 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002126 NOTE: This method should be used after installing application:
2127 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002128 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002129 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002130 Description:
2131 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002132 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002133 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002134 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002135 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002136 cmdStr += " -j"
2137 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002138 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002139 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002140 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002141 except AssertionError:
2142 main.log.exception( "" )
2143 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002144 except TypeError:
2145 main.log.exception( self.name + ": Object not as expected" )
2146 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002147 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002148 main.log.error( self.name + ": EOF exception found" )
2149 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002150 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002151 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002152 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002153 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002154
pingping-lin54b03372015-08-13 14:43:10 -07002155 def ipv4RouteNumber( self ):
2156 """
2157 NOTE: This method should be used after installing application:
2158 onos-app-sdnip
2159 Description:
2160 Obtain the total IPv4 routes number in the system
2161 """
2162 try:
Pratik Parab57963572017-05-09 11:37:54 -07002163 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002164 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002165 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002166 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002167 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002168 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002169 except AssertionError:
2170 main.log.exception( "" )
2171 return None
2172 except ( TypeError, ValueError ):
2173 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002174 return None
2175 except pexpect.EOF:
2176 main.log.error( self.name + ": EOF exception found" )
2177 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002178 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002179 except Exception:
2180 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002181 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002182
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002183 # =============Function to check Bandwidth allocation========
Jon Hall0e240372018-05-02 11:21:57 -07002184 def allocations( self, jsonFormat = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002185 """
2186 Description:
2187 Obtain Bandwidth Allocation Information from ONOS cli.
2188 """
2189 try:
2190 cmdStr = "allocations"
2191 if jsonFormat:
2192 cmdStr += " -j"
Jon Hall0e240372018-05-02 11:21:57 -07002193 handle = self.sendline( cmdStr, timeout=300 )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002194 assert handle is not None, "Error in sendline"
2195 assert "Command not found:" not in handle, handle
2196 return handle
2197 except AssertionError:
2198 main.log.exception( "" )
2199 return None
2200 except ( TypeError, ValueError ):
2201 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2202 return None
2203 except pexpect.EOF:
2204 main.log.error( self.name + ": EOF exception found" )
2205 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002206 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002207 except Exception:
2208 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002209 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002210
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002211 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002212 """
andrewonlabe6745342014-10-17 14:29:13 -04002213 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002214 Obtain intents from the ONOS cli.
2215 Optional:
2216 * jsonFormat: Enable output formatting in json, default to True
2217 * summary: Whether only output the intent summary, defaults to False
2218 * type: Only output a certain type of intent. This options is valid
2219 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002220 """
andrewonlabe6745342014-10-17 14:29:13 -04002221 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002222 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002223 if summary:
2224 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002225 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002226 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002227 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002228 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002229 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002230 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002231 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002232 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002233 else:
Jon Hallff566d52016-01-15 14:45:36 -08002234 intentType = ""
2235 # IF we want the summary of a specific intent type
2236 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002237 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002238 if intentType in jsonResult.keys():
2239 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002240 else:
Jon Hallff566d52016-01-15 14:45:36 -08002241 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002242 return handle
2243 else:
2244 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002245 except AssertionError:
2246 main.log.exception( "" )
2247 return None
2248 except ( TypeError, ValueError ):
2249 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002250 return None
2251 except pexpect.EOF:
2252 main.log.error( self.name + ": EOF exception found" )
2253 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002254 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002255 except Exception:
2256 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002257 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002258
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002259 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002260 """
You Wangfdcbfc42016-05-16 12:16:53 -07002261 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002262 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002263 list of intent IDs.
2264 Parameters:
2265 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002266 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002267 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002268 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002269 accepted.
2270 Returns a list of dictionaries if a list of intent IDs is accepted,
2271 and each dictionary maps 'id' to the Intent ID and 'state' to
2272 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002273 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002274
kelvin-onlab54400a92015-02-26 18:05:51 -08002275 try:
2276 state = "State is Undefined"
2277 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002278 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002279 else:
Jon Hallc6793552016-01-19 14:18:37 -08002280 rawJson = intentsJson
2281 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002282 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002283 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002284 if intentsId == intent[ 'id' ]:
2285 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002286 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002287 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002288 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002289 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002290 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002291 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002292 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002293 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002294 for intent in parsedIntentsJson:
2295 if intentsId[ i ] == intent[ 'id' ]:
2296 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002297 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002298 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002299 break
Jon Hallefbd9792015-03-05 16:11:36 -08002300 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002301 main.log.warn( "Could not find all intents in ONOS output" )
2302 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002303 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002304 else:
Jon Hall53158082017-05-18 11:17:00 -07002305 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002306 return None
Jon Hallc6793552016-01-19 14:18:37 -08002307 except ( TypeError, ValueError ):
2308 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002309 return None
2310 except pexpect.EOF:
2311 main.log.error( self.name + ": EOF exception found" )
2312 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002313 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002314 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002315 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002316 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002317
Jon Hallf539eb92017-05-22 17:18:42 -07002318 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002319 """
2320 Description:
2321 Check intents state
2322 Required:
2323 intentsId - List of intents ID to be checked
2324 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002325 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002326 state in the list.
2327 *NOTE: You can pass in a list of expected state,
2328 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002329 Return:
Jon Hall53158082017-05-18 11:17:00 -07002330 Returns main.TRUE only if all intent are the same as expected states,
2331 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002332 """
2333 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002334 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002335 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002336
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002337 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002338 intentsDict = []
2339 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002340 if isinstance( intentsId, types.StringType ) \
2341 and intent.get( 'id' ) == intentsId:
2342 intentsDict.append( intent )
2343 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002344 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002345 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002346
2347 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002348 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002349 "getting intents state" )
2350 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002351
2352 if isinstance( expectedState, types.StringType ):
2353 for intents in intentsDict:
2354 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002355 main.log.debug( self.name + " : Intent ID - " +
2356 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002357 " actual state = " +
2358 intents.get( 'state' )
2359 + " does not equal expected state = "
2360 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002361 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002362 elif isinstance( expectedState, types.ListType ):
2363 for intents in intentsDict:
2364 if not any( state == intents.get( 'state' ) for state in
2365 expectedState ):
2366 main.log.debug( self.name + " : Intent ID - " +
2367 intents.get( 'id' ) +
2368 " actual state = " +
2369 intents.get( 'state' ) +
2370 " does not equal expected states = "
2371 + str( expectedState ) )
2372 returnValue = main.FALSE
2373
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002374 if returnValue == main.TRUE:
2375 main.log.info( self.name + ": All " +
2376 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002377 " intents are in " + str( expectedState ) +
2378 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002379 return returnValue
2380 except TypeError:
2381 main.log.exception( self.name + ": Object not as expected" )
2382 return None
2383 except pexpect.EOF:
2384 main.log.error( self.name + ": EOF exception found" )
2385 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002386 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002387 except Exception:
2388 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002389 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002390
Jon Hallf539eb92017-05-22 17:18:42 -07002391 def compareBandwidthAllocations( self, expectedAllocations ):
2392 """
2393 Description:
2394 Compare the allocated bandwidth with the given allocations
2395 Required:
2396 expectedAllocations - The expected ONOS output of the allocations command
2397 Return:
2398 Returns main.TRUE only if all intent are the same as expected states,
2399 otherwise returns main.FALSE.
2400 """
2401 # FIXME: Convert these string comparisons to object comparisons
2402 try:
2403 returnValue = main.TRUE
2404 bandwidthFailed = False
2405 rawAlloc = self.allocations()
2406 expectedFormat = StringIO( expectedAllocations )
2407 ONOSOutput = StringIO( rawAlloc )
2408 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2409 str( expectedFormat ) ) )
2410
2411 for actual, expected in izip( ONOSOutput, expectedFormat ):
2412 actual = actual.rstrip()
2413 expected = expected.rstrip()
2414 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2415 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002416 marker1 = actual.find( 'allocated' )
2417 m1 = actual[ :marker1 ]
2418 marker2 = expected.find( 'allocated' )
2419 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002420 if m1 != m2:
2421 bandwidthFailed = True
2422 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2423 bandwidthFailed = True
2424 expectedFormat.close()
2425 ONOSOutput.close()
2426
2427 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002428 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002429 returnValue = main.FALSE
2430 return returnValue
2431 except TypeError:
2432 main.log.exception( self.name + ": Object not as expected" )
2433 return None
2434 except pexpect.EOF:
2435 main.log.error( self.name + ": EOF exception found" )
2436 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002437 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002438 except Exception:
2439 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002440 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002441
You Wang66518af2016-05-16 15:32:59 -07002442 def compareIntent( self, intentDict ):
2443 """
2444 Description:
2445 Compare the intent ids and states provided in the argument with all intents in ONOS
2446 Return:
2447 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2448 Arguments:
2449 intentDict: a dictionary which maps intent ids to intent states
2450 """
2451 try:
2452 intentsRaw = self.intents()
2453 intentsJson = json.loads( intentsRaw )
2454 intentDictONOS = {}
2455 for intent in intentsJson:
2456 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002457 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002458 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002459 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002460 str( len( intentDict ) ) + " expected and " +
2461 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002462 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002463 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002464 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002465 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2466 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002467 else:
2468 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2469 main.log.debug( self.name + ": intent ID - " + intentID +
2470 " expected state is " + intentDict[ intentID ] +
2471 " but actual state is " + intentDictONOS[ intentID ] )
2472 returnValue = main.FALSE
2473 intentDictONOS.pop( intentID )
2474 if len( intentDictONOS ) > 0:
2475 returnValue = main.FALSE
2476 for intentID in intentDictONOS.keys():
2477 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002478 if returnValue == main.TRUE:
2479 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2480 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002481 except KeyError:
2482 main.log.exception( self.name + ": KeyError exception found" )
2483 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002484 except ( TypeError, ValueError ):
2485 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002486 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002487 except pexpect.EOF:
2488 main.log.error( self.name + ": EOF exception found" )
2489 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002490 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002491 except Exception:
2492 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002493 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002494
YPZhang14a4aa92016-07-15 13:37:15 -07002495 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002496 """
2497 Description:
2498 Check the number of installed intents.
2499 Optional:
2500 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002501 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002502 Return:
2503 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2504 , otherwise, returns main.FALSE.
2505 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002506
GlennRCed771242016-01-13 17:02:47 -08002507 try:
2508 cmd = "intents -s -j"
2509
2510 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002511 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002512 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002513 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002514 response = json.loads( response )
2515
2516 # get total and installed number, see if they are match
2517 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002518 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002519 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2520 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002521 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002522 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2523 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002524 return main.FALSE
2525
Jon Hallc6793552016-01-19 14:18:37 -08002526 except ( TypeError, ValueError ):
2527 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002528 return None
2529 except pexpect.EOF:
2530 main.log.error( self.name + ": EOF exception found" )
2531 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002532 if noExit:
2533 return main.FALSE
2534 else:
Devin Lim44075962017-08-11 10:56:37 -07002535 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002536 except pexpect.TIMEOUT:
2537 main.log.error( self.name + ": ONOS timeout" )
2538 return None
GlennRCed771242016-01-13 17:02:47 -08002539 except Exception:
2540 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002541 if noExit:
2542 return main.FALSE
2543 else:
Devin Lim44075962017-08-11 10:56:37 -07002544 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002545
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002546 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002547 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002548 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002549 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002550 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002551 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002552 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002553 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002554 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002555 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002556 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002557 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002558 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002559 cmdStr += " -n"
2560 cmdStr += " " + state
2561 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002562 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002563 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002564 assert "Command not found:" not in handle, handle
2565 if re.search( "Error:", handle ):
2566 main.log.error( self.name + ": flows() response: " +
2567 str( handle ) )
2568 return handle
2569 except AssertionError:
2570 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002571 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002572 except TypeError:
2573 main.log.exception( self.name + ": Object not as expected" )
2574 return None
Jon Hallc6793552016-01-19 14:18:37 -08002575 except pexpect.TIMEOUT:
2576 main.log.error( self.name + ": ONOS timeout" )
2577 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002578 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002579 main.log.error( self.name + ": EOF exception found" )
2580 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002581 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002582 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002583 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002584 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002585
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002586 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002587 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002588 count = int( count ) if count else 0
2589 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002590
Jon Halle0f0b342017-04-18 11:43:47 -07002591 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002592 """
2593 Description:
GlennRCed771242016-01-13 17:02:47 -08002594 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002595 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2596 if the count of those states is 0, which means all current flows
2597 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002598 Optional:
GlennRCed771242016-01-13 17:02:47 -08002599 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002600 Return:
2601 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002602 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002603 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002604 """
2605 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002606 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002607 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002608 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002609 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002610 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002611 if rawFlows:
2612 # if we didn't get flows or flows function return None, we should return
2613 # main.Flase
2614 checkedStates.append( json.loads( rawFlows ) )
2615 else:
2616 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002617 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002618 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002619 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002620 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002621 except TypeError:
2622 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002623 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002624
GlennRCed771242016-01-13 17:02:47 -08002625 # We want to count PENDING_ADD if isPENDING is true
2626 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002627 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002628 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002629 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002630 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002631 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002632 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002633 except ( TypeError, ValueError ):
2634 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002635 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002636
YPZhang240842b2016-05-17 12:00:50 -07002637 except AssertionError:
2638 main.log.exception( "" )
2639 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002640 except pexpect.TIMEOUT:
2641 main.log.error( self.name + ": ONOS timeout" )
2642 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002643 except pexpect.EOF:
2644 main.log.error( self.name + ": EOF exception found" )
2645 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002646 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002647 except Exception:
2648 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002649 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002650
GlennRCed771242016-01-13 17:02:47 -08002651 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002652 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002653 """
andrewonlab87852b02014-11-19 18:44:19 -05002654 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002655 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002656 a specific point-to-point intent definition
2657 Required:
GlennRCed771242016-01-13 17:02:47 -08002658 * ingress: specify source dpid
2659 * egress: specify destination dpid
2660 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002661 Optional:
GlennRCed771242016-01-13 17:02:47 -08002662 * offset: the keyOffset is where the next batch of intents
2663 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002664 * noExit: If set to True, TestON will not exit if any error when issus command
2665 * getResponse: If set to True, function will return ONOS response.
2666
GlennRCed771242016-01-13 17:02:47 -08002667 Returns: If failed to push test intents, it will returen None,
2668 if successful, return true.
2669 Timeout expection will return None,
2670 TypeError will return false
2671 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002672 """
andrewonlab87852b02014-11-19 18:44:19 -05002673 try:
GlennRCed771242016-01-13 17:02:47 -08002674 if background:
2675 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002676 else:
GlennRCed771242016-01-13 17:02:47 -08002677 back = ""
2678 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002679 ingress,
2680 egress,
2681 batchSize,
2682 offset,
2683 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002684 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002685 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002686 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002687 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002688 if getResponse:
2689 return response
2690
GlennRCed771242016-01-13 17:02:47 -08002691 # TODO: We should handle if there is failure in installation
2692 return main.TRUE
2693
Jon Hallc6793552016-01-19 14:18:37 -08002694 except AssertionError:
2695 main.log.exception( "" )
2696 return None
GlennRCed771242016-01-13 17:02:47 -08002697 except pexpect.TIMEOUT:
2698 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002699 return None
andrewonlab87852b02014-11-19 18:44:19 -05002700 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002701 main.log.error( self.name + ": EOF exception found" )
2702 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002703 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002704 except TypeError:
2705 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002706 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002707 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002708 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002709 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002710
YPZhangebf9eb52016-05-12 15:20:24 -07002711 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002712 """
2713 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002714 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002715 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002716 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002717 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002718 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002719
YPZhangb5d3f832016-01-23 22:54:26 -08002720 try:
YPZhange3109a72016-02-02 11:25:37 -08002721 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002722 cmd = "flows -c added"
2723 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2724 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002725 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002726 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002727 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002728 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002729 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002730 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002731 return None
2732 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002733
You Wangd3cb2ce2016-05-16 14:01:24 -07002734 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002735 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002736 return None
2737 except pexpect.EOF:
2738 main.log.error( self.name + ": EOF exception found" )
2739 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002740 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002741 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002742 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002743 except pexpect.TIMEOUT:
2744 main.log.error( self.name + ": ONOS timeout" )
2745 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002746 except Exception:
2747 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002748 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002749 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002750 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002751
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002752 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002753 """
2754 Description:
2755 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002756 Optional:
2757 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002758 Return:
2759 The number of intents
2760 """
2761 try:
2762 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002763 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002764 if response is None:
2765 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002766 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002767 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002768 except ( TypeError, ValueError ):
2769 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002770 return None
2771 except pexpect.EOF:
2772 main.log.error( self.name + ": EOF exception found" )
2773 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002774 if noExit:
2775 return -1
2776 else:
Devin Lim44075962017-08-11 10:56:37 -07002777 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002778 except Exception:
2779 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002780 if noExit:
2781 return -1
2782 else:
Devin Lim44075962017-08-11 10:56:37 -07002783 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002784
kelvin-onlabd3b64892015-01-20 13:26:24 -08002785 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002786 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002787 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002788 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002789 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002790 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002791 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002792 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002793 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002794 cmdStr += " -j"
2795 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002796 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002797 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002798 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002799 except AssertionError:
2800 main.log.exception( "" )
2801 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002802 except TypeError:
2803 main.log.exception( self.name + ": Object not as expected" )
2804 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002805 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002806 main.log.error( self.name + ": EOF exception found" )
2807 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002808 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002809 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002810 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002811 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002812
kelvin-onlabd3b64892015-01-20 13:26:24 -08002813 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002814 """
2815 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002816 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002817 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002818 """
andrewonlab867212a2014-10-22 20:13:38 -04002819 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002820 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002821 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002822 cmdStr += " -j"
2823 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002824 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002825 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002826 if handle:
2827 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002828 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002829 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002830 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002831 else:
2832 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002833 except AssertionError:
2834 main.log.exception( "" )
2835 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002836 except TypeError:
2837 main.log.exception( self.name + ": Object not as expected" )
2838 return None
andrewonlab867212a2014-10-22 20:13:38 -04002839 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002840 main.log.error( self.name + ": EOF exception found" )
2841 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002842 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002843 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002844 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002845 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002846
kelvin8ec71442015-01-15 16:57:00 -08002847 # Wrapper functions ****************
2848 # Wrapper functions use existing driver
2849 # functions and extends their use case.
2850 # For example, we may use the output of
2851 # a normal driver function, and parse it
2852 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002853
kelvin-onlabd3b64892015-01-20 13:26:24 -08002854 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002855 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002856 Description:
2857 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002858 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002859 try:
kelvin8ec71442015-01-15 16:57:00 -08002860 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002861 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002862 if intentsStr is None:
2863 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002864 # Convert to a dictionary
2865 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002866 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002867 for intent in intents:
2868 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002869 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002870 except TypeError:
2871 main.log.exception( self.name + ": Object not as expected" )
2872 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002873 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002874 main.log.error( self.name + ": EOF exception found" )
2875 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002876 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002877 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002878 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002879 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002880
You Wang3c276252016-09-21 15:21:36 -07002881 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002882 """
2883 Determine the number of flow rules for the given device id that are
2884 in the added state
You Wang3c276252016-09-21 15:21:36 -07002885 Params:
2886 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002887 """
2888 try:
You Wang3c276252016-09-21 15:21:36 -07002889 if core:
2890 cmdStr = "flows any " + str( deviceId ) + " | " +\
2891 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2892 else:
2893 cmdStr = "flows any " + str( deviceId ) + " | " +\
2894 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002895 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002896 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002897 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002898 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002899 except AssertionError:
2900 main.log.exception( "" )
2901 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002902 except pexpect.EOF:
2903 main.log.error( self.name + ": EOF exception found" )
2904 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002905 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002906 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002907 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002908 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002909
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002910 def groupAddedCount( self, deviceId, core=False ):
2911 """
2912 Determine the number of group rules for the given device id that are
2913 in the added state
2914 Params:
2915 core: if True, only return the number of core groups added
2916 """
2917 try:
2918 if core:
2919 cmdStr = "groups any " + str( deviceId ) + " | " +\
2920 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2921 else:
2922 cmdStr = "groups any " + str( deviceId ) + " | " +\
2923 "grep 'state=ADDED' | wc -l"
2924 handle = self.sendline( cmdStr )
2925 assert handle is not None, "Error in sendline"
2926 assert "Command not found:" not in handle, handle
2927 return handle
2928 except AssertionError:
2929 main.log.exception( "" )
2930 return None
2931 except pexpect.EOF:
2932 main.log.error( self.name + ": EOF exception found" )
2933 main.log.error( self.name + ": " + self.handle.before )
2934 main.cleanAndExit()
2935 except Exception:
2936 main.log.exception( self.name + ": Uncaught exception!" )
2937 main.cleanAndExit()
2938
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002939 def addStaticRoute( self, subnet, intf):
2940 """
2941 Adds a static route to onos.
2942 Params:
2943 subnet: The subnet reaching through this route
2944 intf: The interface this route is reachable through
2945 """
2946 try:
2947 cmdStr = "route-add " + subnet + " " + intf
2948 handle = self.sendline( cmdStr )
2949 assert handle is not None, "Error in sendline"
2950 assert "Command not found:" not in handle, handle
2951 return handle
2952 except AssertionError:
2953 main.log.exception( "" )
2954 return None
2955 except pexpect.EOF:
2956 main.log.error( self.name + ": EOF exception found" )
2957 main.log.error( self.name + ": " + self.handle.before )
2958 main.cleanAndExit()
2959 except Exception:
2960 main.log.exception( self.name + ": Uncaught exception!" )
2961 main.cleanAndExit()
2962
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002963 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
2964 """
2965 Description:
2966 Check whether the number of groups for the given device id that
2967 are in ADDED state is bigger than minGroupCount.
2968 Required:
2969 * deviceId: device id to check the number of added group rules
2970 Optional:
2971 * minGroupCount: the number of groups to compare
2972 * core: if True, only check the number of core groups added
2973 * comparison: if 0, compare with greater than minFlowCount
2974 * if 1, compare with equal to minFlowCount
2975 Return:
2976 Returns the number of groups if it is bigger than minGroupCount,
2977 returns main.FALSE otherwise.
2978 """
2979 count = self.groupAddedCount( deviceId, core )
2980 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07002981 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002982 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
2983
You Wangc02f3be2018-05-18 12:14:23 -07002984 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002985 """
2986 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07002987 deviceId: Id of the device from which we retrieve groups
2988 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002989 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002990 try:
You Wangc02f3be2018-05-18 12:14:23 -07002991 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
2992 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002993 assert handle is not None, "Error in sendline"
2994 assert "Command not found:" not in handle, handle
2995 return handle
2996 except AssertionError:
2997 main.log.exception( "" )
2998 return None
2999 except TypeError:
3000 main.log.exception( self.name + ": Object not as expected" )
3001 return None
3002 except pexpect.EOF:
3003 main.log.error( self.name + ": EOF exception found" )
3004 main.log.error( self.name + ": " + self.handle.before )
3005 main.cleanAndExit()
3006 except Exception:
3007 main.log.exception( self.name + ": Uncaught exception!" )
3008 main.cleanAndExit()
3009
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003010 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003011 """
3012 Description:
3013 Check whether the number of flow rules for the given device id that
3014 are in ADDED state is bigger than minFlowCount.
3015 Required:
3016 * deviceId: device id to check the number of added flow rules
3017 Optional:
3018 * minFlowCount: the number of flow rules to compare
3019 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08003020 * comparison: if 0, compare with greater than minFlowCount
3021 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003022 Return:
3023 Returns the number of flow rules if it is bigger than minFlowCount,
3024 returns main.FALSE otherwise.
3025 """
3026 count = self.flowAddedCount( deviceId, core )
3027 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07003028 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08003029 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08003030
kelvin-onlabd3b64892015-01-20 13:26:24 -08003031 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003032 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003033 Use 'devices' function to obtain list of all devices
3034 and parse the result to obtain a list of all device
3035 id's. Returns this list. Returns empty list if no
3036 devices exist
kelvin8ec71442015-01-15 16:57:00 -08003037 List is ordered sequentially
3038
andrewonlab3e15ead2014-10-15 14:21:34 -04003039 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003040 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003041 the ids. By obtaining the list of device ids on the fly,
3042 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003043 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003044 try:
kelvin8ec71442015-01-15 16:57:00 -08003045 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003046 devicesStr = self.devices( jsonFormat=False )
3047 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003048
kelvin-onlabd3b64892015-01-20 13:26:24 -08003049 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003050 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003051 return idList
kelvin8ec71442015-01-15 16:57:00 -08003052
3053 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003054 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003055 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003056 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003057 # Split list further into arguments before and after string
3058 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003059 # append to idList
3060 for arg in tempList:
3061 idList.append( arg.split( "id=" )[ 1 ] )
3062 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003063
Jon Halld4d4b372015-01-28 16:02:41 -08003064 except TypeError:
3065 main.log.exception( self.name + ": Object not as expected" )
3066 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003067 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003068 main.log.error( self.name + ": EOF exception found" )
3069 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003070 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003071 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003072 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003073 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003074
kelvin-onlabd3b64892015-01-20 13:26:24 -08003075 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003076 """
andrewonlab7c211572014-10-15 16:45:20 -04003077 Uses 'nodes' function to obtain list of all nodes
3078 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003079 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003080 Returns:
3081 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003082 """
andrewonlab7c211572014-10-15 16:45:20 -04003083 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003084 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003085 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003086 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003087 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003088 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003089 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003090 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003091 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003092 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003093 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003094 except ( TypeError, ValueError ):
3095 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003096 return None
andrewonlab7c211572014-10-15 16:45:20 -04003097 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003098 main.log.error( self.name + ": EOF exception found" )
3099 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003100 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003101 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003102 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003103 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003104
kelvin-onlabd3b64892015-01-20 13:26:24 -08003105 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003106 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003107 Return the first device from the devices api whose 'id' contains 'dpid'
3108 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003109 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003110 try:
kelvin8ec71442015-01-15 16:57:00 -08003111 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003112 return None
3113 else:
kelvin8ec71442015-01-15 16:57:00 -08003114 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003115 rawDevices = self.devices()
3116 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003117 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003118 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003119 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3120 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003121 return device
3122 return None
Jon Hallc6793552016-01-19 14:18:37 -08003123 except ( TypeError, ValueError ):
3124 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003125 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003127 main.log.error( self.name + ": EOF exception found" )
3128 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003129 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003130 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003131 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003132 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003133
You Wang24139872016-05-03 11:48:47 -07003134 def getTopology( self, topologyOutput ):
3135 """
3136 Definition:
3137 Loads a json topology output
3138 Return:
3139 topology = current ONOS topology
3140 """
3141 import json
3142 try:
3143 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003144 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003145 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003146 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003147 except ( TypeError, ValueError ):
3148 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3149 return None
You Wang24139872016-05-03 11:48:47 -07003150 except pexpect.EOF:
3151 main.log.error( self.name + ": EOF exception found" )
3152 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003153 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003154 except Exception:
3155 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003156 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003157
Pier6a0c4de2018-03-18 16:01:30 -07003158 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003159 """
Jon Hallefbd9792015-03-05 16:11:36 -08003160 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003161 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003162 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003163
Flavio Castro82ee2f62016-06-07 15:04:12 -07003164 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003165 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003166 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003167 logLevel = level to log to.
3168 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003169
Jon Hallefbd9792015-03-05 16:11:36 -08003170 Returns: main.TRUE if the number of switches and links are correct,
3171 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003172 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003173 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003174 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003175 try:
You Wang13310252016-07-31 10:56:14 -07003176 summary = self.summary()
3177 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003178 except ( TypeError, ValueError ):
3179 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3180 return main.ERROR
3181 try:
3182 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003183 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003184 return main.ERROR
3185 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003186 # Is the number of switches is what we expected
3187 devices = topology.get( 'devices', False )
3188 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003189 nodes = summary.get( 'nodes', False )
3190 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003191 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003192 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003193 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003194 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003195 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3196 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003197 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003198 output = output + "The number of links and switches match "\
3199 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003200 result = main.TRUE
3201 else:
You Wang24139872016-05-03 11:48:47 -07003202 output = output + \
3203 "The number of links and switches does not match " + \
3204 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003205 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003206 output = output + "\n ONOS sees %i devices" % int( devices )
3207 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003208 if int( numolink ) > 0:
3209 output = output + "and %i links " % int( links )
3210 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003211 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003212 output = output + "and %i controllers " % int( nodes )
3213 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003214 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003215 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003216 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003217 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003218 else:
You Wang24139872016-05-03 11:48:47 -07003219 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003220 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003221 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003222 main.log.error( self.name + ": EOF exception found" )
3223 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003224 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003225 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003226 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003227 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003228
kelvin-onlabd3b64892015-01-20 13:26:24 -08003229 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003230 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003231 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003232 deviceId must be the id of a device as seen in the onos devices command
3233 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003234 role must be either master, standby, or none
3235
Jon Halle3f39ff2015-01-13 11:50:53 -08003236 Returns:
3237 main.TRUE or main.FALSE based on argument verification and
3238 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003239 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003240 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003241 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003242 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003243 cmdStr = "device-role " +\
3244 str( deviceId ) + " " +\
3245 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003246 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003247 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003248 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003249 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003250 if re.search( "Error", handle ):
3251 # end color output to escape any colours
3252 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003253 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003254 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003255 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003256 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003257 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003258 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003259 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003260 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003261 except AssertionError:
3262 main.log.exception( "" )
3263 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003264 except TypeError:
3265 main.log.exception( self.name + ": Object not as expected" )
3266 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003267 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003268 main.log.error( self.name + ": EOF exception found" )
3269 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003270 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003271 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003272 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003273 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003274
kelvin-onlabd3b64892015-01-20 13:26:24 -08003275 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003276 """
Jon Hall0dd09952018-04-19 09:59:11 -07003277 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003278 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003279 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003280 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003281 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003282 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003283 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003284 cmdStr += " -j"
3285 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003286 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003287 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003288 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003289 except AssertionError:
3290 main.log.exception( "" )
3291 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003292 except TypeError:
3293 main.log.exception( self.name + ": Object not as expected" )
3294 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003295 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003296 main.log.error( self.name + ": EOF exception found" )
3297 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003298 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003299 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003300 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003301 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003302
kelvin-onlabd3b64892015-01-20 13:26:24 -08003303 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003304 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003305 CLI command to get the current leader for the Election test application
3306 NOTE: Requires installation of the onos-app-election feature
3307 Returns: Node IP of the leader if one exists
3308 None if none exists
3309 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003310 """
Jon Hall94fd0472014-12-08 11:52:42 -08003311 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003312 cmdStr = "election-test-leader"
3313 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003314 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003315 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003316 # Leader
3317 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003318 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003319 nodeSearch = re.search( leaderPattern, response )
3320 if nodeSearch:
3321 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003322 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003323 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003324 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003325 # no leader
3326 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003327 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003328 nullSearch = re.search( nullPattern, response )
3329 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003330 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003331 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003332 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003333 # error
Jon Hall0e240372018-05-02 11:21:57 -07003334 main.log.error( self.name + ": Error in electionTestLeader on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003335 ": " + "unexpected response" )
3336 main.log.error( repr( response ) )
3337 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003338 except AssertionError:
3339 main.log.exception( "" )
3340 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003341 except TypeError:
3342 main.log.exception( self.name + ": Object not as expected" )
3343 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003344 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003345 main.log.error( self.name + ": EOF exception found" )
3346 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003347 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003348 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003349 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003350 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003351
kelvin-onlabd3b64892015-01-20 13:26:24 -08003352 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003353 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003354 CLI command to run for leadership of the Election test application.
3355 NOTE: Requires installation of the onos-app-election feature
3356 Returns: Main.TRUE on success
3357 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003358 """
Jon Hall94fd0472014-12-08 11:52:42 -08003359 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003360 cmdStr = "election-test-run"
3361 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003362 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003363 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003364 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003365 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003366 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003367 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003368 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003369 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003370 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003371 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003372 # error
Jon Hall0e240372018-05-02 11:21:57 -07003373 main.log.error( self.name + ": Error in electionTestRun on " + self.name +
Jon Hall97cf84a2016-06-20 13:35:58 -07003374 ": " + "unexpected response" )
3375 main.log.error( repr( response ) )
3376 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003377 except AssertionError:
3378 main.log.exception( "" )
3379 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003380 except TypeError:
3381 main.log.exception( self.name + ": Object not as expected" )
3382 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003383 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003384 main.log.error( self.name + ": EOF exception found" )
3385 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003386 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003387 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003388 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003389 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003390
kelvin-onlabd3b64892015-01-20 13:26:24 -08003391 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003392 """
Jon Hall94fd0472014-12-08 11:52:42 -08003393 * CLI command to withdraw the local node from leadership election for
3394 * the Election test application.
3395 #NOTE: Requires installation of the onos-app-election feature
3396 Returns: Main.TRUE on success
3397 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003398 """
Jon Hall94fd0472014-12-08 11:52:42 -08003399 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003400 cmdStr = "election-test-withdraw"
3401 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003402 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003403 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003404 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003405 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003406 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003407 if re.search( successPattern, response ):
3408 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003409 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003410 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003411 # error
Jon Hall0e240372018-05-02 11:21:57 -07003412 main.log.error( self.name + ": Error in electionTestWithdraw on " +
Jon Hall97cf84a2016-06-20 13:35:58 -07003413 self.name + ": " + "unexpected response" )
3414 main.log.error( repr( response ) )
3415 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003416 except AssertionError:
3417 main.log.exception( "" )
3418 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003419 except TypeError:
3420 main.log.exception( self.name + ": Object not as expected" )
3421 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003422 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003423 main.log.error( self.name + ": EOF exception found" )
3424 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003425 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003426 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003427 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003428 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003429
kelvin8ec71442015-01-15 16:57:00 -08003430 def getDevicePortsEnabledCount( self, dpid ):
3431 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003432 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003433 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003434 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003435 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003436 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3437 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003438 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003439 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003440 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003441 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003442 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003443 return output
Jon Hallc6793552016-01-19 14:18:37 -08003444 except AssertionError:
3445 main.log.exception( "" )
3446 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003447 except TypeError:
3448 main.log.exception( self.name + ": Object not as expected" )
3449 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003450 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003451 main.log.error( self.name + ": EOF exception found" )
3452 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003453 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003454 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003455 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003456 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003457
kelvin8ec71442015-01-15 16:57:00 -08003458 def getDeviceLinksActiveCount( self, dpid ):
3459 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003460 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003461 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003462 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003463 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003464 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3465 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003466 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003467 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003468 if re.search( "No such device", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003469 main.log.error( self.name + ": Error in getting ports " )
kelvin-onlab898a6c62015-01-16 14:13:53 -08003470 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003471 return output
Jon Hallc6793552016-01-19 14:18:37 -08003472 except AssertionError:
3473 main.log.exception( "" )
3474 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003475 except TypeError:
3476 main.log.exception( self.name + ": Object not as expected" )
3477 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003478 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003479 main.log.error( self.name + ": EOF exception found" )
3480 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003481 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003482 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003483 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003484 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003485
kelvin8ec71442015-01-15 16:57:00 -08003486 def getAllIntentIds( self ):
3487 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003488 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003489 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003490 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003491 cmdStr = "onos:intents | grep id="
3492 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003493 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003494 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003495 if re.search( "Error", output ):
Jon Hall0e240372018-05-02 11:21:57 -07003496 main.log.error( self.name + ": Error in getting ports" )
Jon Halle3f39ff2015-01-13 11:50:53 -08003497 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003498 return output
Jon Hallc6793552016-01-19 14:18:37 -08003499 except AssertionError:
3500 main.log.exception( "" )
3501 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003502 except TypeError:
3503 main.log.exception( self.name + ": Object not as expected" )
3504 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003505 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003506 main.log.error( self.name + ": EOF exception found" )
3507 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003508 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003509 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003510 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003511 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003512
Jon Hall73509952015-02-24 16:42:56 -08003513 def intentSummary( self ):
3514 """
Jon Hallefbd9792015-03-05 16:11:36 -08003515 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003516 """
3517 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003518 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003519 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003520 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003521 states.append( intent.get( 'state', None ) )
3522 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003523 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003524 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003525 except ( TypeError, ValueError ):
3526 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003527 return None
3528 except pexpect.EOF:
3529 main.log.error( self.name + ": EOF exception found" )
3530 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003531 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003532 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003533 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003534 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003535
Jon Hall61282e32015-03-19 11:34:11 -07003536 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003537 """
3538 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003539 Optional argument:
3540 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003541 """
Jon Hall63604932015-02-26 17:09:50 -08003542 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003543 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003544 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003545 cmdStr += " -j"
3546 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003547 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003548 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003549 return output
Jon Hallc6793552016-01-19 14:18:37 -08003550 except AssertionError:
3551 main.log.exception( "" )
3552 return None
Jon Hall63604932015-02-26 17:09:50 -08003553 except TypeError:
3554 main.log.exception( self.name + ": Object not as expected" )
3555 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003556 except pexpect.EOF:
3557 main.log.error( self.name + ": EOF exception found" )
3558 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003559 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003560 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003561 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003562 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003563
acsmarsa4a4d1e2015-07-10 16:01:24 -07003564 def leaderCandidates( self, jsonFormat=True ):
3565 """
3566 Returns the output of the leaders -c command.
3567 Optional argument:
3568 * jsonFormat - boolean indicating if you want output in json
3569 """
3570 try:
3571 cmdStr = "onos:leaders -c"
3572 if jsonFormat:
3573 cmdStr += " -j"
3574 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003575 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003576 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003577 return output
Jon Hallc6793552016-01-19 14:18:37 -08003578 except AssertionError:
3579 main.log.exception( "" )
3580 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003581 except TypeError:
3582 main.log.exception( self.name + ": Object not as expected" )
3583 return None
3584 except pexpect.EOF:
3585 main.log.error( self.name + ": EOF exception found" )
3586 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003587 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003588 except Exception:
3589 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003590 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003591
Jon Hallc6793552016-01-19 14:18:37 -08003592 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003593 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003594 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003595 topic parameter and an empty list if the topic doesn't exist
3596 If no leader is elected leader in the returned list will be "none"
3597 Returns None if there is a type error processing the json object
3598 """
3599 try:
Jon Hall6e709752016-02-01 13:38:46 -08003600 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003601 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003602 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003603 assert "Command not found:" not in rawOutput, rawOutput
3604 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003605 results = []
3606 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003607 if dict[ "topic" ] == topic:
3608 leader = dict[ "leader" ]
3609 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003610 results.append( leader )
3611 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003612 return results
Jon Hallc6793552016-01-19 14:18:37 -08003613 except AssertionError:
3614 main.log.exception( "" )
3615 return None
3616 except ( TypeError, ValueError ):
3617 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003618 return None
3619 except pexpect.EOF:
3620 main.log.error( self.name + ": EOF exception found" )
3621 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003622 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003623 except Exception:
3624 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003625 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003626
Jon Hall61282e32015-03-19 11:34:11 -07003627 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003628 """
3629 Returns the output of the intent Pending map.
3630 """
Jon Hall63604932015-02-26 17:09:50 -08003631 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003632 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003633 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003634 cmdStr += " -j"
3635 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003636 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003637 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003638 return output
Jon Hallc6793552016-01-19 14:18:37 -08003639 except AssertionError:
3640 main.log.exception( "" )
3641 return None
Jon Hall63604932015-02-26 17:09:50 -08003642 except TypeError:
3643 main.log.exception( self.name + ": Object not as expected" )
3644 return None
3645 except pexpect.EOF:
3646 main.log.error( self.name + ": EOF exception found" )
3647 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003648 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003649 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003650 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003651 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003652
Jon Hall2c8959e2016-12-16 12:17:34 -08003653 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003654 """
3655 Returns the output of the raft partitions command for ONOS.
3656 """
Jon Hall61282e32015-03-19 11:34:11 -07003657 # Sample JSON
3658 # {
3659 # "leader": "tcp://10.128.30.11:7238",
3660 # "members": [
3661 # "tcp://10.128.30.11:7238",
3662 # "tcp://10.128.30.17:7238",
3663 # "tcp://10.128.30.13:7238",
3664 # ],
3665 # "name": "p1",
3666 # "term": 3
3667 # },
Jon Hall63604932015-02-26 17:09:50 -08003668 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003669 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003670 if candidates:
3671 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003672 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003673 cmdStr += " -j"
3674 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003675 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003676 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003677 return output
Jon Hallc6793552016-01-19 14:18:37 -08003678 except AssertionError:
3679 main.log.exception( "" )
3680 return None
Jon Hall63604932015-02-26 17:09:50 -08003681 except TypeError:
3682 main.log.exception( self.name + ": Object not as expected" )
3683 return None
3684 except pexpect.EOF:
3685 main.log.error( self.name + ": EOF exception found" )
3686 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003687 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003688 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003689 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003690 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003691
Jon Halle9f909e2016-09-23 10:43:12 -07003692 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003693 """
3694 Returns the output of the apps command for ONOS. This command lists
3695 information about installed ONOS applications
3696 """
3697 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003698 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003699 # "description":"ONOS OpenFlow protocol southbound providers",
3700 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003701 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003702 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003703 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003704 if summary:
3705 cmdStr += " -s"
3706 if active:
3707 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003708 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003709 cmdStr += " -j"
3710 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003711 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003712 assert "Command not found:" not in output, output
3713 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003714 return output
Jon Hallbe379602015-03-24 13:39:32 -07003715 # FIXME: look at specific exceptions/Errors
3716 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07003717 main.log.exception( self.name + ": Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003718 return None
3719 except TypeError:
3720 main.log.exception( self.name + ": Object not as expected" )
3721 return None
3722 except pexpect.EOF:
3723 main.log.error( self.name + ": EOF exception found" )
3724 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003725 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003726 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003727 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003728 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003729
Jon Hall146f1522015-03-24 15:33:24 -07003730 def appStatus( self, appName ):
3731 """
3732 Uses the onos:apps cli command to return the status of an application.
3733 Returns:
3734 "ACTIVE" - If app is installed and activated
3735 "INSTALLED" - If app is installed and deactivated
3736 "UNINSTALLED" - If app is not installed
3737 None - on error
3738 """
Jon Hall146f1522015-03-24 15:33:24 -07003739 try:
3740 if not isinstance( appName, types.StringType ):
3741 main.log.error( self.name + ".appStatus(): appName must be" +
3742 " a string" )
3743 return None
3744 output = self.apps( jsonFormat=True )
3745 appsJson = json.loads( output )
3746 state = None
3747 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003748 if appName == app.get( 'name' ):
3749 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003750 break
3751 if state == "ACTIVE" or state == "INSTALLED":
3752 return state
3753 elif state is None:
Jon Hall8bafdc02017-09-05 11:36:26 -07003754 main.log.warn( "{} app not found", appName )
Jon Hall146f1522015-03-24 15:33:24 -07003755 return "UNINSTALLED"
3756 elif state:
3757 main.log.error( "Unexpected state from 'onos:apps': " +
3758 str( state ) )
3759 return state
Jon Hallc6793552016-01-19 14:18:37 -08003760 except ( TypeError, ValueError ):
3761 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003762 return None
3763 except pexpect.EOF:
3764 main.log.error( self.name + ": EOF exception found" )
3765 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003766 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003767 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003768 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003769 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003770
Jon Hallbe379602015-03-24 13:39:32 -07003771 def app( self, appName, option ):
3772 """
3773 Interacts with the app command for ONOS. This command manages
3774 application inventory.
3775 """
Jon Hallbe379602015-03-24 13:39:32 -07003776 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003777 # Validate argument types
3778 valid = True
3779 if not isinstance( appName, types.StringType ):
3780 main.log.error( self.name + ".app(): appName must be a " +
3781 "string" )
3782 valid = False
3783 if not isinstance( option, types.StringType ):
3784 main.log.error( self.name + ".app(): option must be a string" )
3785 valid = False
3786 if not valid:
3787 return main.FALSE
3788 # Validate Option
3789 option = option.lower()
3790 # NOTE: Install may become a valid option
3791 if option == "activate":
3792 pass
3793 elif option == "deactivate":
3794 pass
3795 elif option == "uninstall":
3796 pass
3797 else:
3798 # Invalid option
3799 main.log.error( "The ONOS app command argument only takes " +
3800 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003801 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003802 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003803 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003804 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003805 assert output is not None, "Error in sendline"
3806 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003807 if "Error executing command" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003808 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hallbe379602015-03-24 13:39:32 -07003809 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003810 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003811 elif "No such application" in output:
3812 main.log.error( "The application '" + appName +
3813 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003814 return main.FALSE
3815 elif "Command not found:" in output:
Jon Hall0e240372018-05-02 11:21:57 -07003816 main.log.error( self.name + ": Error in processing onos:app command: " +
Jon Hall146f1522015-03-24 15:33:24 -07003817 str( output ) )
3818 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003819 elif "Unsupported command:" in output:
3820 main.log.error( "Incorrect command given to 'app': " +
3821 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003822 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003823 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003824 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003825 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003826 except AssertionError:
3827 main.log.exception( self.name + ": AssertionError exception found" )
3828 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003829 except TypeError:
3830 main.log.exception( self.name + ": Object not as expected" )
3831 return main.ERROR
3832 except pexpect.EOF:
3833 main.log.error( self.name + ": EOF exception found" )
3834 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003835 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003836 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003837 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003838 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003839
Jon Hallbd16b922015-03-26 17:53:15 -07003840 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003841 """
3842 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003843 appName is the hierarchical app name, not the feature name
3844 If check is True, method will check the status of the app after the
3845 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003846 Returns main.TRUE if the command was successfully sent
3847 main.FALSE if the cli responded with an error or given
3848 incorrect input
3849 """
3850 try:
3851 if not isinstance( appName, types.StringType ):
3852 main.log.error( self.name + ".activateApp(): appName must be" +
3853 " a string" )
3854 return main.FALSE
3855 status = self.appStatus( appName )
3856 if status == "INSTALLED":
3857 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003858 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003859 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003860 status = self.appStatus( appName )
3861 if status == "ACTIVE":
3862 return main.TRUE
3863 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003864 main.log.debug( "The state of application " +
3865 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003866 time.sleep( 1 )
3867 return main.FALSE
3868 else: # not 'check' or command didn't succeed
3869 return response
Jon Hall146f1522015-03-24 15:33:24 -07003870 elif status == "ACTIVE":
3871 return main.TRUE
3872 elif status == "UNINSTALLED":
3873 main.log.error( self.name + ": Tried to activate the " +
3874 "application '" + appName + "' which is not " +
3875 "installed." )
3876 else:
3877 main.log.error( "Unexpected return value from appStatus: " +
3878 str( status ) )
3879 return main.ERROR
3880 except TypeError:
3881 main.log.exception( self.name + ": Object not as expected" )
3882 return main.ERROR
3883 except pexpect.EOF:
3884 main.log.error( self.name + ": EOF exception found" )
3885 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003886 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003887 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003888 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003889 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003890
Jon Hallbd16b922015-03-26 17:53:15 -07003891 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003892 """
3893 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003894 appName is the hierarchical app name, not the feature name
3895 If check is True, method will check the status of the app after the
3896 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003897 Returns main.TRUE if the command was successfully sent
3898 main.FALSE if the cli responded with an error or given
3899 incorrect input
3900 """
3901 try:
3902 if not isinstance( appName, types.StringType ):
3903 main.log.error( self.name + ".deactivateApp(): appName must " +
3904 "be a string" )
3905 return main.FALSE
3906 status = self.appStatus( appName )
3907 if status == "INSTALLED":
3908 return main.TRUE
3909 elif status == "ACTIVE":
3910 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003911 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003912 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003913 status = self.appStatus( appName )
3914 if status == "INSTALLED":
3915 return main.TRUE
3916 else:
3917 time.sleep( 1 )
3918 return main.FALSE
3919 else: # not check or command didn't succeed
3920 return response
Jon Hall146f1522015-03-24 15:33:24 -07003921 elif status == "UNINSTALLED":
3922 main.log.warn( self.name + ": Tried to deactivate the " +
3923 "application '" + appName + "' which is not " +
3924 "installed." )
3925 return main.TRUE
3926 else:
3927 main.log.error( "Unexpected return value from appStatus: " +
3928 str( status ) )
3929 return main.ERROR
3930 except TypeError:
3931 main.log.exception( self.name + ": Object not as expected" )
3932 return main.ERROR
3933 except pexpect.EOF:
3934 main.log.error( self.name + ": EOF exception found" )
3935 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003936 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003937 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003938 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003939 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003940
Jon Hallbd16b922015-03-26 17:53:15 -07003941 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003942 """
3943 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003944 appName is the hierarchical app name, not the feature name
3945 If check is True, method will check the status of the app after the
3946 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003947 Returns main.TRUE if the command was successfully sent
3948 main.FALSE if the cli responded with an error or given
3949 incorrect input
3950 """
3951 # TODO: check with Thomas about the state machine for apps
3952 try:
3953 if not isinstance( appName, types.StringType ):
3954 main.log.error( self.name + ".uninstallApp(): appName must " +
3955 "be a string" )
3956 return main.FALSE
3957 status = self.appStatus( appName )
3958 if status == "INSTALLED":
3959 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003960 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003961 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003962 status = self.appStatus( appName )
3963 if status == "UNINSTALLED":
3964 return main.TRUE
3965 else:
3966 time.sleep( 1 )
3967 return main.FALSE
3968 else: # not check or command didn't succeed
3969 return response
Jon Hall146f1522015-03-24 15:33:24 -07003970 elif status == "ACTIVE":
3971 main.log.warn( self.name + ": Tried to uninstall the " +
3972 "application '" + appName + "' which is " +
3973 "currently active." )
3974 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003975 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003976 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003977 status = self.appStatus( appName )
3978 if status == "UNINSTALLED":
3979 return main.TRUE
3980 else:
3981 time.sleep( 1 )
3982 return main.FALSE
3983 else: # not check or command didn't succeed
3984 return response
Jon Hall146f1522015-03-24 15:33:24 -07003985 elif status == "UNINSTALLED":
3986 return main.TRUE
3987 else:
3988 main.log.error( "Unexpected return value from appStatus: " +
3989 str( status ) )
3990 return main.ERROR
3991 except TypeError:
3992 main.log.exception( self.name + ": Object not as expected" )
3993 return main.ERROR
3994 except pexpect.EOF:
3995 main.log.error( self.name + ": EOF exception found" )
3996 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003997 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003998 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003999 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004000 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004001
4002 def appIDs( self, jsonFormat=True ):
4003 """
4004 Show the mappings between app id and app names given by the 'app-ids'
4005 cli command
4006 """
4007 try:
4008 cmdStr = "app-ids"
4009 if jsonFormat:
4010 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07004011 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004012 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004013 assert "Command not found:" not in output, output
4014 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07004015 return output
Jon Hallbd16b922015-03-26 17:53:15 -07004016 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004017 main.log.exception( self.name + ": Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07004018 return None
4019 except TypeError:
4020 main.log.exception( self.name + ": Object not as expected" )
4021 return None
4022 except pexpect.EOF:
4023 main.log.error( self.name + ": EOF exception found" )
4024 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004025 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004026 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004027 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004028 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004029
4030 def appToIDCheck( self ):
4031 """
4032 This method will check that each application's ID listed in 'apps' is
4033 the same as the ID listed in 'app-ids'. The check will also check that
4034 there are no duplicate IDs issued. Note that an app ID should be
4035 a globaly unique numerical identifier for app/app-like features. Once
4036 an ID is registered, the ID is never freed up so that if an app is
4037 reinstalled it will have the same ID.
4038
4039 Returns: main.TRUE if the check passes and
4040 main.FALSE if the check fails or
4041 main.ERROR if there is some error in processing the test
4042 """
4043 try:
Jon Hall0e240372018-05-02 11:21:57 -07004044 # Grab IDs
Jon Hallc6793552016-01-19 14:18:37 -08004045 rawJson = self.appIDs( jsonFormat=True )
4046 if rawJson:
4047 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004048 else:
Jon Hall0e240372018-05-02 11:21:57 -07004049 main.log.error( "app-ids returned nothing: " + repr( rawJson ) )
4050 return main.FALSE
4051
4052 # Grab Apps
Jon Hallc6793552016-01-19 14:18:37 -08004053 rawJson = self.apps( jsonFormat=True )
4054 if rawJson:
4055 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004056 else:
Jon Hallc6793552016-01-19 14:18:37 -08004057 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004058 return main.FALSE
Jon Hall0e240372018-05-02 11:21:57 -07004059
Jon Hallbd16b922015-03-26 17:53:15 -07004060 result = main.TRUE
4061 for app in apps:
4062 appID = app.get( 'id' )
4063 if appID is None:
4064 main.log.error( "Error parsing app: " + str( app ) )
4065 result = main.FALSE
4066 appName = app.get( 'name' )
4067 if appName is None:
4068 main.log.error( "Error parsing app: " + str( app ) )
4069 result = main.FALSE
4070 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004071 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004072 if not current: # if ids doesn't have this id
4073 result = main.FALSE
4074 main.log.error( "'app-ids' does not have the ID for " +
4075 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004076 main.log.debug( "apps command returned: " + str( app ) +
4077 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004078 elif len( current ) > 1:
4079 # there is more than one app with this ID
4080 result = main.FALSE
4081 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004082 elif not current[ 0 ][ 'name' ] == appName:
4083 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004084 result = main.FALSE
4085 main.log.error( "'app-ids' has " + str( currentName ) +
4086 " registered under id:" + str( appID ) +
4087 " but 'apps' has " + str( appName ) )
4088 else:
4089 pass # id and name match!
Jon Hall0e240372018-05-02 11:21:57 -07004090
Jon Hallbd16b922015-03-26 17:53:15 -07004091 # now make sure that app-ids has no duplicates
4092 idsList = []
4093 namesList = []
4094 for item in ids:
4095 idsList.append( item[ 'id' ] )
4096 namesList.append( item[ 'name' ] )
4097 if len( idsList ) != len( set( idsList ) ) or\
4098 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004099 main.log.error( "'app-ids' has some duplicate entries: \n"
4100 + json.dumps( ids,
4101 sort_keys=True,
4102 indent=4,
4103 separators=( ',', ': ' ) ) )
4104 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004105 return result
Jon Hallc6793552016-01-19 14:18:37 -08004106 except ( TypeError, ValueError ):
4107 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004108 return main.ERROR
4109 except pexpect.EOF:
4110 main.log.error( self.name + ": EOF exception found" )
4111 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004112 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004113 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004114 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004115 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004116
Jon Hallfb760a02015-04-13 15:35:03 -07004117 def getCfg( self, component=None, propName=None, short=False,
4118 jsonFormat=True ):
4119 """
4120 Get configuration settings from onos cli
4121 Optional arguments:
4122 component - Optionally only list configurations for a specific
4123 component. If None, all components with configurations
4124 are displayed. Case Sensitive string.
4125 propName - If component is specified, propName option will show
4126 only this specific configuration from that component.
4127 Case Sensitive string.
4128 jsonFormat - Returns output as json. Note that this will override
4129 the short option
4130 short - Short, less verbose, version of configurations.
4131 This is overridden by the json option
4132 returns:
4133 Output from cli as a string or None on error
4134 """
4135 try:
4136 baseStr = "cfg"
4137 cmdStr = " get"
4138 componentStr = ""
4139 if component:
4140 componentStr += " " + component
4141 if propName:
4142 componentStr += " " + propName
4143 if jsonFormat:
4144 baseStr += " -j"
4145 elif short:
4146 baseStr += " -s"
4147 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004148 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004149 assert "Command not found:" not in output, output
4150 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004151 return output
4152 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004153 main.log.exception( self.name + ": Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004154 return None
4155 except TypeError:
4156 main.log.exception( self.name + ": Object not as expected" )
4157 return None
4158 except pexpect.EOF:
4159 main.log.error( self.name + ": EOF exception found" )
4160 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004161 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004162 except Exception:
4163 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004164 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004165
4166 def setCfg( self, component, propName, value=None, check=True ):
4167 """
4168 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004169 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004170 component - The case sensitive name of the component whose
4171 property is to be set
4172 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004173 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004174 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004175 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004176 check - Boolean, Check whether the option was successfully set this
4177 only applies when a value is given.
4178 returns:
4179 main.TRUE on success or main.FALSE on failure. If check is False,
4180 will return main.TRUE unless there is an error
4181 """
4182 try:
4183 baseStr = "cfg"
4184 cmdStr = " set " + str( component ) + " " + str( propName )
4185 if value is not None:
4186 cmdStr += " " + str( value )
4187 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004188 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004189 assert "Command not found:" not in output, output
4190 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004191 if value and check:
4192 results = self.getCfg( component=str( component ),
4193 propName=str( propName ),
4194 jsonFormat=True )
4195 # Check if current value is what we just set
4196 try:
4197 jsonOutput = json.loads( results )
4198 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004199 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004200 main.log.exception( "Error parsing cfg output" )
4201 main.log.error( "output:" + repr( results ) )
4202 return main.FALSE
4203 if current == str( value ):
4204 return main.TRUE
4205 return main.FALSE
4206 return main.TRUE
4207 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004208 main.log.exception( self.name + ": Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004209 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004210 except ( TypeError, ValueError ):
4211 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004212 return main.FALSE
4213 except pexpect.EOF:
4214 main.log.error( self.name + ": EOF exception found" )
4215 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004216 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004217 except Exception:
4218 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004219 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004220
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004221 def distPrimitivesSend( self, cmd ):
4222 """
4223 Function to handle sending cli commands for the distributed primitives test app
4224
4225 This command will catch some exceptions and retry the command on some
4226 specific store exceptions.
4227
4228 Required arguments:
4229 cmd - The command to send to the cli
4230 returns:
4231 string containing the cli output
4232 None on Error
4233 """
4234 try:
4235 output = self.sendline( cmd )
4236 try:
4237 assert output is not None, "Error in sendline"
4238 # TODO: Maybe make this less hardcoded
4239 # ConsistentMap Exceptions
4240 assert "org.onosproject.store.service" not in output
4241 # Node not leader
4242 assert "java.lang.IllegalStateException" not in output
4243 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004244 main.log.error( self.name + ": Error in processing '" + cmd + "' " +
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004245 "command: " + str( output ) )
4246 retryTime = 30 # Conservative time, given by Madan
4247 main.log.info( "Waiting " + str( retryTime ) +
4248 "seconds before retrying." )
4249 time.sleep( retryTime ) # Due to change in mastership
4250 output = self.sendline( cmd )
4251 assert output is not None, "Error in sendline"
4252 assert "Command not found:" not in output, output
4253 assert "Error executing command" not in output, output
4254 main.log.info( self.name + ": " + output )
4255 return output
4256 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004257 main.log.exception( self.name + ": Error in processing '" + cmd + "' command." )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004258 return None
4259 except TypeError:
4260 main.log.exception( self.name + ": Object not as expected" )
4261 return None
4262 except pexpect.EOF:
4263 main.log.error( self.name + ": EOF exception found" )
4264 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004265 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004266 except Exception:
4267 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004268 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004269
Jon Hall390696c2015-05-05 17:13:41 -07004270 def setTestAdd( self, setName, values ):
4271 """
4272 CLI command to add elements to a distributed set.
4273 Arguments:
4274 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004275 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004276 Example usages:
4277 setTestAdd( "set1", "a b c" )
4278 setTestAdd( "set2", "1" )
4279 returns:
4280 main.TRUE on success OR
4281 main.FALSE if elements were already in the set OR
4282 main.ERROR on error
4283 """
4284 try:
4285 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004286 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004287 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4288 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004289 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004290 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004291 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004292 return main.FALSE
4293 else:
4294 main.log.error( self.name + ": setTestAdd did not" +
4295 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004296 main.log.debug( self.name + " actual: " + repr( output ) )
4297 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004298 except TypeError:
4299 main.log.exception( self.name + ": Object not as expected" )
4300 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004301 except Exception:
4302 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004303 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004304
4305 def setTestRemove( self, setName, values, clear=False, retain=False ):
4306 """
4307 CLI command to remove elements from a distributed set.
4308 Required arguments:
4309 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004310 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004311 Optional arguments:
4312 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004313 retain - Retain only the given values. (intersection of the
4314 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004315 returns:
4316 main.TRUE on success OR
4317 main.FALSE if the set was not changed OR
4318 main.ERROR on error
4319 """
4320 try:
4321 cmdStr = "set-test-remove "
4322 if clear:
4323 cmdStr += "-c " + str( setName )
4324 elif retain:
4325 cmdStr += "-r " + str( setName ) + " " + str( values )
4326 else:
4327 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004328 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004329 if clear:
4330 pattern = "Set " + str( setName ) + " cleared"
4331 if re.search( pattern, output ):
4332 return main.TRUE
4333 elif retain:
4334 positivePattern = str( setName ) + " was pruned to contain " +\
4335 "only elements of set \[(.*)\]"
4336 negativePattern = str( setName ) + " was not changed by " +\
4337 "retaining only elements of the set " +\
4338 "\[(.*)\]"
4339 if re.search( positivePattern, output ):
4340 return main.TRUE
4341 elif re.search( negativePattern, output ):
4342 return main.FALSE
4343 else:
4344 positivePattern = "\[(.*)\] was removed from the set " +\
4345 str( setName )
4346 if ( len( values.split() ) == 1 ):
4347 negativePattern = "\[(.*)\] was not in set " +\
4348 str( setName )
4349 else:
4350 negativePattern = "No element of \[(.*)\] was in set " +\
4351 str( setName )
4352 if re.search( positivePattern, output ):
4353 return main.TRUE
4354 elif re.search( negativePattern, output ):
4355 return main.FALSE
4356 main.log.error( self.name + ": setTestRemove did not" +
4357 " match expected output" )
4358 main.log.debug( self.name + " expected: " + pattern )
4359 main.log.debug( self.name + " actual: " + repr( output ) )
4360 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004361 except TypeError:
4362 main.log.exception( self.name + ": Object not as expected" )
4363 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004364 except Exception:
4365 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004366 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004367
4368 def setTestGet( self, setName, values="" ):
4369 """
4370 CLI command to get the elements in a distributed set.
4371 Required arguments:
4372 setName - The name of the set to remove from.
4373 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004374 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004375 returns:
4376 main.ERROR on error OR
4377 A list of elements in the set if no optional arguments are
4378 supplied OR
4379 A tuple containing the list then:
4380 main.FALSE if the given values are not in the set OR
4381 main.TRUE if the given values are in the set OR
4382 """
4383 try:
4384 values = str( values ).strip()
4385 setName = str( setName ).strip()
4386 length = len( values.split() )
4387 containsCheck = None
4388 # Patterns to match
4389 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004390 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004391 containsTrue = "Set " + setName + " contains the value " + values
4392 containsFalse = "Set " + setName + " did not contain the value " +\
4393 values
4394 containsAllTrue = "Set " + setName + " contains the the subset " +\
4395 setPattern
4396 containsAllFalse = "Set " + setName + " did not contain the the" +\
4397 " subset " + setPattern
4398
4399 cmdStr = "set-test-get "
4400 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004401 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004402 if length == 0:
4403 match = re.search( pattern, output )
4404 else: # if given values
4405 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004406 patternTrue = pattern + "\r\n" + containsTrue
4407 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004408 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004409 patternTrue = pattern + "\r\n" + containsAllTrue
4410 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004411 matchTrue = re.search( patternTrue, output )
4412 matchFalse = re.search( patternFalse, output )
4413 if matchTrue:
4414 containsCheck = main.TRUE
4415 match = matchTrue
4416 elif matchFalse:
4417 containsCheck = main.FALSE
4418 match = matchFalse
4419 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004420 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004421 "expected output" )
4422 main.log.debug( self.name + " expected: " + pattern )
4423 main.log.debug( self.name + " actual: " + repr( output ) )
4424 match = None
4425 if match:
4426 setMatch = match.group( 1 )
4427 if setMatch == '':
4428 setList = []
4429 else:
4430 setList = setMatch.split( ", " )
4431 if length > 0:
4432 return ( setList, containsCheck )
4433 else:
4434 return setList
4435 else: # no match
4436 main.log.error( self.name + ": setTestGet did not" +
4437 " match expected output" )
4438 main.log.debug( self.name + " expected: " + pattern )
4439 main.log.debug( self.name + " actual: " + repr( output ) )
4440 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004441 except TypeError:
4442 main.log.exception( self.name + ": Object not as expected" )
4443 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004444 except Exception:
4445 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004446 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004447
4448 def setTestSize( self, setName ):
4449 """
4450 CLI command to get the elements in a distributed set.
4451 Required arguments:
4452 setName - The name of the set to remove from.
4453 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004454 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004455 None on error
4456 """
4457 try:
4458 # TODO: Should this check against the number of elements returned
4459 # and then return true/false based on that?
4460 setName = str( setName ).strip()
4461 # Patterns to match
4462 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004463 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004464 setPattern
4465 cmdStr = "set-test-get -s "
4466 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004467 output = self.distPrimitivesSend( cmdStr )
Jon Hall0e240372018-05-02 11:21:57 -07004468 if output:
4469 match = re.search( pattern, output )
4470 if match:
4471 setSize = int( match.group( 1 ) )
4472 setMatch = match.group( 2 )
4473 if len( setMatch.split() ) == setSize:
4474 main.log.info( "The size returned by " + self.name +
4475 " matches the number of elements in " +
4476 "the returned set" )
4477 else:
4478 main.log.error( "The size returned by " + self.name +
4479 " does not match the number of " +
4480 "elements in the returned set." )
4481 return setSize
Jon Hall390696c2015-05-05 17:13:41 -07004482 else: # no match
4483 main.log.error( self.name + ": setTestGet did not" +
4484 " match expected output" )
4485 main.log.debug( self.name + " expected: " + pattern )
4486 main.log.debug( self.name + " actual: " + repr( output ) )
4487 return None
Jon Hall390696c2015-05-05 17:13:41 -07004488 except TypeError:
4489 main.log.exception( self.name + ": Object not as expected" )
4490 return None
Jon Hall390696c2015-05-05 17:13:41 -07004491 except Exception:
4492 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004493 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004494
Jon Hall80daded2015-05-27 16:07:00 -07004495 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004496 """
4497 Command to list the various counters in the system.
4498 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004499 if jsonFormat, a string of the json object returned by the cli
4500 command
4501 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004502 None on error
4503 """
Jon Hall390696c2015-05-05 17:13:41 -07004504 try:
Jon Hall390696c2015-05-05 17:13:41 -07004505 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004506 if jsonFormat:
4507 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004508 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004509 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004510 assert "Command not found:" not in output, output
4511 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004512 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004513 return output
Jon Hall390696c2015-05-05 17:13:41 -07004514 except AssertionError:
Jon Hall0e240372018-05-02 11:21:57 -07004515 main.log.exception( self.name + ": Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004516 return None
Jon Hall390696c2015-05-05 17:13:41 -07004517 except TypeError:
4518 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004519 return None
Jon Hall390696c2015-05-05 17:13:41 -07004520 except pexpect.EOF:
4521 main.log.error( self.name + ": EOF exception found" )
4522 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004523 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004524 except Exception:
4525 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004526 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004527
Jon Hall935db192016-04-19 00:22:04 -07004528 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004529 """
Jon Halle1a3b752015-07-22 13:02:46 -07004530 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004531 Required arguments:
4532 counter - The name of the counter to increment.
4533 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004534 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004535 returns:
4536 integer value of the counter or
4537 None on Error
4538 """
4539 try:
4540 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004541 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004542 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004543 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004544 if delta != 1:
4545 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004546 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004547 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004548 match = re.search( pattern, output )
4549 if match:
4550 return int( match.group( 1 ) )
4551 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004552 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004553 " match expected output." )
4554 main.log.debug( self.name + " expected: " + pattern )
4555 main.log.debug( self.name + " actual: " + repr( output ) )
4556 return None
Jon Hall390696c2015-05-05 17:13:41 -07004557 except TypeError:
4558 main.log.exception( self.name + ": Object not as expected" )
4559 return None
Jon Hall390696c2015-05-05 17:13:41 -07004560 except Exception:
4561 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004562 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004563
Jon Hall935db192016-04-19 00:22:04 -07004564 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004565 """
4566 CLI command to get a distributed counter then add a delta to it.
4567 Required arguments:
4568 counter - The name of the counter to increment.
4569 Optional arguments:
4570 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004571 returns:
4572 integer value of the counter or
4573 None on Error
4574 """
4575 try:
4576 counter = str( counter )
4577 delta = int( delta )
4578 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004579 cmdStr += counter
4580 if delta != 1:
4581 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004582 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004583 pattern = counter + " was updated to (-?\d+)"
4584 match = re.search( pattern, output )
4585 if match:
4586 return int( match.group( 1 ) )
4587 else:
4588 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4589 " match expected output." )
4590 main.log.debug( self.name + " expected: " + pattern )
4591 main.log.debug( self.name + " actual: " + repr( output ) )
4592 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004593 except TypeError:
4594 main.log.exception( self.name + ": Object not as expected" )
4595 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004596 except Exception:
4597 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004598 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004599
4600 def valueTestGet( self, valueName ):
4601 """
4602 CLI command to get the value of an atomic value.
4603 Required arguments:
4604 valueName - The name of the value to get.
4605 returns:
4606 string value of the value or
4607 None on Error
4608 """
4609 try:
4610 valueName = str( valueName )
4611 cmdStr = "value-test "
4612 operation = "get"
4613 cmdStr = "value-test {} {}".format( valueName,
4614 operation )
4615 output = self.distPrimitivesSend( cmdStr )
4616 pattern = "(\w+)"
4617 match = re.search( pattern, output )
4618 if match:
4619 return match.group( 1 )
4620 else:
4621 main.log.error( self.name + ": valueTestGet did not" +
4622 " match expected output." )
4623 main.log.debug( self.name + " expected: " + pattern )
4624 main.log.debug( self.name + " actual: " + repr( output ) )
4625 return None
4626 except TypeError:
4627 main.log.exception( self.name + ": Object not as expected" )
4628 return None
4629 except Exception:
4630 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004631 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004632
4633 def valueTestSet( self, valueName, newValue ):
4634 """
4635 CLI command to set the value of an atomic value.
4636 Required arguments:
4637 valueName - The name of the value to set.
4638 newValue - The value to assign to the given value.
4639 returns:
4640 main.TRUE on success or
4641 main.ERROR on Error
4642 """
4643 try:
4644 valueName = str( valueName )
4645 newValue = str( newValue )
4646 operation = "set"
4647 cmdStr = "value-test {} {} {}".format( valueName,
4648 operation,
4649 newValue )
4650 output = self.distPrimitivesSend( cmdStr )
4651 if output is not None:
4652 return main.TRUE
4653 else:
4654 return main.ERROR
4655 except TypeError:
4656 main.log.exception( self.name + ": Object not as expected" )
4657 return main.ERROR
4658 except Exception:
4659 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004660 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004661
4662 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4663 """
4664 CLI command to compareAndSet the value of an atomic value.
4665 Required arguments:
4666 valueName - The name of the value.
4667 oldValue - Compare the current value of the atomic value to this
4668 newValue - If the value equals oldValue, set the value to newValue
4669 returns:
4670 main.TRUE on success or
4671 main.FALSE on failure or
4672 main.ERROR on Error
4673 """
4674 try:
4675 valueName = str( valueName )
4676 oldValue = str( oldValue )
4677 newValue = str( newValue )
4678 operation = "compareAndSet"
4679 cmdStr = "value-test {} {} {} {}".format( valueName,
4680 operation,
4681 oldValue,
4682 newValue )
4683 output = self.distPrimitivesSend( cmdStr )
4684 pattern = "(\w+)"
4685 match = re.search( pattern, output )
4686 if match:
4687 result = match.group( 1 )
4688 if result == "true":
4689 return main.TRUE
4690 elif result == "false":
4691 return main.FALSE
4692 else:
4693 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4694 " match expected output." )
4695 main.log.debug( self.name + " expected: " + pattern )
4696 main.log.debug( self.name + " actual: " + repr( output ) )
4697 return main.ERROR
4698 except TypeError:
4699 main.log.exception( self.name + ": Object not as expected" )
4700 return main.ERROR
4701 except Exception:
4702 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004703 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004704
4705 def valueTestGetAndSet( self, valueName, newValue ):
4706 """
4707 CLI command to getAndSet the value of an atomic value.
4708 Required arguments:
4709 valueName - The name of the value to get.
4710 newValue - The value to assign to the given value
4711 returns:
4712 string value of the value or
4713 None on Error
4714 """
4715 try:
4716 valueName = str( valueName )
4717 cmdStr = "value-test "
4718 operation = "getAndSet"
4719 cmdStr += valueName + " " + operation
4720 cmdStr = "value-test {} {} {}".format( valueName,
4721 operation,
4722 newValue )
4723 output = self.distPrimitivesSend( cmdStr )
4724 pattern = "(\w+)"
4725 match = re.search( pattern, output )
4726 if match:
4727 return match.group( 1 )
4728 else:
4729 main.log.error( self.name + ": valueTestGetAndSet did not" +
4730 " match expected output." )
4731 main.log.debug( self.name + " expected: " + pattern )
4732 main.log.debug( self.name + " actual: " + repr( output ) )
4733 return None
4734 except TypeError:
4735 main.log.exception( self.name + ": Object not as expected" )
4736 return None
4737 except Exception:
4738 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004739 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004740
4741 def valueTestDestroy( self, valueName ):
4742 """
4743 CLI command to destroy an atomic value.
4744 Required arguments:
4745 valueName - The name of the value to destroy.
4746 returns:
4747 main.TRUE on success or
4748 main.ERROR on Error
4749 """
4750 try:
4751 valueName = str( valueName )
4752 cmdStr = "value-test "
4753 operation = "destroy"
4754 cmdStr += valueName + " " + operation
4755 output = self.distPrimitivesSend( cmdStr )
4756 if output is not None:
4757 return main.TRUE
4758 else:
4759 return main.ERROR
4760 except TypeError:
4761 main.log.exception( self.name + ": Object not as expected" )
4762 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004763 except Exception:
4764 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004765 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004766
YPZhangfebf7302016-05-24 16:45:56 -07004767 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004768 """
4769 Description: Execute summary command in onos
4770 Returns: json object ( summary -j ), returns main.FALSE if there is
4771 no output
4772
4773 """
4774 try:
4775 cmdStr = "summary"
4776 if jsonFormat:
4777 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004778 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004779 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004780 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004781 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004782 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004783 if not handle:
4784 main.log.error( self.name + ": There is no output in " +
4785 "summary command" )
4786 return main.FALSE
4787 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004788 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004789 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004790 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004791 except TypeError:
4792 main.log.exception( self.name + ": Object not as expected" )
4793 return None
4794 except pexpect.EOF:
4795 main.log.error( self.name + ": EOF exception found" )
4796 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004797 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004798 except Exception:
4799 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004800 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004801
Jon Hall935db192016-04-19 00:22:04 -07004802 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004803 """
4804 CLI command to get the value of a key in a consistent map using
4805 transactions. This a test function and can only get keys from the
4806 test map hard coded into the cli command
4807 Required arguments:
4808 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004809 returns:
4810 The string value of the key or
4811 None on Error
4812 """
4813 try:
4814 keyName = str( keyName )
4815 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004816 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004817 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004818 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4819 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004820 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004821 return None
4822 else:
4823 match = re.search( pattern, output )
4824 if match:
4825 return match.groupdict()[ 'value' ]
4826 else:
4827 main.log.error( self.name + ": transactionlMapGet did not" +
4828 " match expected output." )
4829 main.log.debug( self.name + " expected: " + pattern )
4830 main.log.debug( self.name + " actual: " + repr( output ) )
4831 return None
4832 except TypeError:
4833 main.log.exception( self.name + ": Object not as expected" )
4834 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004835 except Exception:
4836 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004837 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004838
Jon Hall935db192016-04-19 00:22:04 -07004839 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004840 """
4841 CLI command to put a value into 'numKeys' number of keys in a
4842 consistent map using transactions. This a test function and can only
4843 put into keys named 'Key#' of the test map hard coded into the cli command
4844 Required arguments:
4845 numKeys - Number of keys to add the value to
4846 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004847 returns:
4848 A dictionary whose keys are the name of the keys put into the map
4849 and the values of the keys are dictionaries whose key-values are
4850 'value': value put into map and optionaly
4851 'oldValue': Previous value in the key or
4852 None on Error
4853
4854 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004855 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4856 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004857 """
4858 try:
4859 numKeys = str( numKeys )
4860 value = str( value )
4861 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004862 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004863 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004864 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4865 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4866 results = {}
4867 for line in output.splitlines():
4868 new = re.search( newPattern, line )
4869 updated = re.search( updatedPattern, line )
4870 if new:
4871 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4872 elif updated:
4873 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004874 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004875 else:
4876 main.log.error( self.name + ": transactionlMapGet did not" +
4877 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004878 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4879 newPattern,
4880 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004881 main.log.debug( self.name + " actual: " + repr( output ) )
4882 return results
Jon Hall0e240372018-05-02 11:21:57 -07004883 except ( TypeError, AttributeError ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004884 main.log.exception( self.name + ": Object not as expected" )
4885 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004886 except Exception:
4887 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004888 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004889
acsmarsdaea66c2015-09-03 11:44:06 -07004890 def maps( self, jsonFormat=True ):
4891 """
4892 Description: Returns result of onos:maps
4893 Optional:
4894 * jsonFormat: enable json formatting of output
4895 """
4896 try:
4897 cmdStr = "maps"
4898 if jsonFormat:
4899 cmdStr += " -j"
4900 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004901 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004902 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004903 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004904 except AssertionError:
4905 main.log.exception( "" )
4906 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004907 except TypeError:
4908 main.log.exception( self.name + ": Object not as expected" )
4909 return None
4910 except pexpect.EOF:
4911 main.log.error( self.name + ": EOF exception found" )
4912 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004913 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004914 except Exception:
4915 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004916 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004917
4918 def getSwController( self, uri, jsonFormat=True ):
4919 """
4920 Descrition: Gets the controller information from the device
4921 """
4922 try:
4923 cmd = "device-controllers "
4924 if jsonFormat:
4925 cmd += "-j "
4926 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004927 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004928 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004929 return response
Jon Hallc6793552016-01-19 14:18:37 -08004930 except AssertionError:
4931 main.log.exception( "" )
4932 return None
GlennRC050596c2015-11-18 17:06:41 -08004933 except TypeError:
4934 main.log.exception( self.name + ": Object not as expected" )
4935 return None
4936 except pexpect.EOF:
4937 main.log.error( self.name + ": EOF exception found" )
4938 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004939 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004940 except Exception:
4941 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004942 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004943
4944 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4945 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004946 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004947
4948 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004949 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08004950 ip - String or List: The ip address of the controller.
4951 This parameter can be formed in a couple of different ways.
4952 VALID:
4953 10.0.0.1 - just the ip address
4954 tcp:10.0.0.1 - the protocol and the ip address
4955 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4956 so that you can add controllers with different
4957 protocols and ports
4958 INVALID:
4959 10.0.0.1:6653 - this is not supported by ONOS
4960
4961 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4962 port - The port number.
4963 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4964
4965 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4966 """
4967 try:
4968 cmd = "device-setcontrollers"
4969
4970 if jsonFormat:
4971 cmd += " -j"
4972 cmd += " " + uri
4973 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004974 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08004975 for item in ip:
4976 if ":" in item:
4977 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004978 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08004979 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004980 elif "." in sitem[ 1 ]:
4981 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08004982 else:
4983 main.log.error( "Malformed entry: " + item )
4984 raise TypeError
4985 else:
4986 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004987 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004988 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004989 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004990 if "Error" in response:
4991 main.log.error( response )
4992 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004993 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004994 except AssertionError:
4995 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004996 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004997 except TypeError:
4998 main.log.exception( self.name + ": Object not as expected" )
4999 return main.FALSE
5000 except pexpect.EOF:
5001 main.log.error( self.name + ": EOF exception found" )
5002 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005003 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08005004 except Exception:
5005 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005006 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005007
5008 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005009 '''
GlennRC20fc6522015-12-23 23:26:57 -08005010 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005011 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08005012 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005013 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08005014 Returns:
5015 Returns main.FALSE if an exception is thrown or an error is present
5016 in the response. Otherwise, returns main.TRUE.
5017 NOTE:
5018 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005019 '''
GlennRC20fc6522015-12-23 23:26:57 -08005020 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005021 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07005022 deviceStr = device
5023 device = []
5024 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08005025
5026 for d in device:
5027 time.sleep( 1 )
5028 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07005029 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005030 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005031 if "Error" in response:
5032 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
5033 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005034 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005035 except AssertionError:
5036 main.log.exception( "" )
5037 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005038 except TypeError:
5039 main.log.exception( self.name + ": Object not as expected" )
5040 return main.FALSE
5041 except pexpect.EOF:
5042 main.log.error( self.name + ": EOF exception found" )
5043 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005044 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005045 except Exception:
5046 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005047 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005048
5049 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005050 '''
GlennRC20fc6522015-12-23 23:26:57 -08005051 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005052 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005053 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005054 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005055 Returns:
5056 Returns main.FALSE if an exception is thrown or an error is present
5057 in the response. Otherwise, returns main.TRUE.
5058 NOTE:
5059 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005060 '''
GlennRC20fc6522015-12-23 23:26:57 -08005061 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005062 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005063 host = list( host )
5064
5065 for h in host:
5066 time.sleep( 1 )
5067 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005068 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005069 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005070 if "Error" in response:
5071 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5072 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005073 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005074 except AssertionError:
5075 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005076 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005077 except TypeError:
5078 main.log.exception( self.name + ": Object not as expected" )
5079 return main.FALSE
5080 except pexpect.EOF:
5081 main.log.error( self.name + ": EOF exception found" )
5082 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005083 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005084 except Exception:
5085 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005086 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005087
YPZhangfebf7302016-05-24 16:45:56 -07005088 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005089 '''
GlennRCed771242016-01-13 17:02:47 -08005090 Description:
5091 Bring link down or up in the null-provider.
5092 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005093 begin - (string) One end of a device or switch.
5094 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005095 returns:
5096 main.TRUE if no exceptions were thrown and no Errors are
5097 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005098 '''
GlennRCed771242016-01-13 17:02:47 -08005099 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005100 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005101 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005102 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005103 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005104 if "Error" in response or "Failure" in response:
5105 main.log.error( response )
5106 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005107 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005108 except AssertionError:
5109 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005110 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005111 except TypeError:
5112 main.log.exception( self.name + ": Object not as expected" )
5113 return main.FALSE
5114 except pexpect.EOF:
5115 main.log.error( self.name + ": EOF exception found" )
5116 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005117 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005118 except Exception:
5119 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005120 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005121
Jon Hall2c8959e2016-12-16 12:17:34 -08005122 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005123 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005124 Description:
5125 Changes the state of port in an OF switch by means of the
5126 PORTSTATUS OF messages.
5127 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005128 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5129 port - (string) target port in the device. Ex: '2'
5130 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005131 returns:
5132 main.TRUE if no exceptions were thrown and no Errors are
5133 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005134 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005135 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005136 state = state.lower()
5137 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005138 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005139 response = self.sendline( cmd, showResponse=True )
5140 assert response is not None, "Error in sendline"
5141 assert "Command not found:" not in response, response
5142 if "Error" in response or "Failure" in response:
5143 main.log.error( response )
5144 return main.FALSE
5145 return main.TRUE
5146 except AssertionError:
5147 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005148 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005149 except TypeError:
5150 main.log.exception( self.name + ": Object not as expected" )
5151 return main.FALSE
5152 except pexpect.EOF:
5153 main.log.error( self.name + ": EOF exception found" )
5154 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005155 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005156 except Exception:
5157 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005158 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005159
5160 def logSet( self, level="INFO", app="org.onosproject" ):
5161 """
5162 Set the logging level to lvl for a specific app
5163 returns main.TRUE on success
5164 returns main.FALSE if Error occurred
5165 if noExit is True, TestON will not exit, but clean up
5166 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5167 Level defaults to INFO
5168 """
5169 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005170 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005171 self.handle.expect( "onos>" )
5172
5173 response = self.handle.before
5174 if re.search( "Error", response ):
5175 return main.FALSE
5176 return main.TRUE
5177 except pexpect.TIMEOUT:
5178 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005179 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005180 except pexpect.EOF:
5181 main.log.error( self.name + ": EOF exception found" )
5182 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005183 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005184 except Exception:
5185 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005186 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005187
5188 def getGraphDict( self, timeout=60, includeHost=False ):
5189 """
5190 Return a dictionary which describes the latest network topology data as a
5191 graph.
5192 An example of the dictionary:
5193 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5194 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5195 Each vertex should at least have an 'edges' attribute which describes the
5196 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005197 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005198 list of attributes.
5199 An example of the edges dictionary:
5200 'edges': { vertex2: { 'port': ..., 'weight': ... },
5201 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005202 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005203 in topology data.
5204 """
5205 graphDict = {}
5206 try:
5207 links = self.links()
5208 links = json.loads( links )
5209 devices = self.devices()
5210 devices = json.loads( devices )
5211 idToDevice = {}
5212 for device in devices:
5213 idToDevice[ device[ 'id' ] ] = device
5214 if includeHost:
5215 hosts = self.hosts()
5216 # FIXME: support 'includeHost' argument
5217 for link in links:
5218 nodeA = link[ 'src' ][ 'device' ]
5219 nodeB = link[ 'dst' ][ 'device' ]
5220 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005221 if nodeA not in graphDict.keys():
5222 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005223 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005224 'type': idToDevice[ nodeA ][ 'type' ],
5225 'available': idToDevice[ nodeA ][ 'available' ],
5226 'role': idToDevice[ nodeA ][ 'role' ],
5227 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5228 'hw': idToDevice[ nodeA ][ 'hw' ],
5229 'sw': idToDevice[ nodeA ][ 'sw' ],
5230 'serial': idToDevice[ nodeA ][ 'serial' ],
5231 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005232 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005233 else:
5234 # Assert nodeB is not connected to any current links of nodeA
5235 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005236 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5237 'type': link[ 'type' ],
5238 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005239 return graphDict
5240 except ( TypeError, ValueError ):
5241 main.log.exception( self.name + ": Object not as expected" )
5242 return None
5243 except KeyError:
5244 main.log.exception( self.name + ": KeyError exception found" )
5245 return None
5246 except AssertionError:
5247 main.log.exception( self.name + ": AssertionError exception found" )
5248 return None
5249 except pexpect.EOF:
5250 main.log.error( self.name + ": EOF exception found" )
5251 main.log.error( self.name + ": " + self.handle.before )
5252 return None
5253 except Exception:
5254 main.log.exception( self.name + ": Uncaught exception!" )
5255 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005256
5257 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005258 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005259 Send command to check intent-perf summary
5260 Returns: dictionary for intent-perf summary
5261 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005262 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005263 cmd = "intent-perf -s"
5264 respDic = {}
5265 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005266 assert resp is not None, "Error in sendline"
5267 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005268 try:
5269 # Generate the dictionary to return
5270 for l in resp.split( "\n" ):
5271 # Delete any white space in line
5272 temp = re.sub( r'\s+', '', l )
5273 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005274 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005275
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005276 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005277 main.log.exception( self.name + ": Object not as expected" )
5278 return None
5279 except KeyError:
5280 main.log.exception( self.name + ": KeyError exception found" )
5281 return None
5282 except AssertionError:
5283 main.log.exception( self.name + ": AssertionError exception found" )
5284 return None
5285 except pexpect.EOF:
5286 main.log.error( self.name + ": EOF exception found" )
5287 main.log.error( self.name + ": " + self.handle.before )
5288 return None
5289 except Exception:
5290 main.log.exception( self.name + ": Uncaught exception!" )
5291 return None
5292 return respDic
5293
Chiyu Chengec63bde2016-11-17 18:11:36 -08005294 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005295 """
5296 Searches the latest ONOS log file for the given search term and
5297 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005298
chengchiyu08303a02016-09-08 17:40:26 -07005299 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005300 searchTerm:
5301 The string to grep from the ONOS log.
5302 startLine:
5303 The term that decides which line is the start to search the searchTerm in
5304 the karaf log. For now, startTerm only works in 'first' mode.
5305 logNum:
5306 In some extreme cases, one karaf log is not big enough to contain all the
5307 information.Because of this, search mutiply logs is necessary to capture
5308 the right result. logNum is the number of karaf logs that we need to search
5309 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005310 mode:
5311 all: return all the strings that contain the search term
5312 last: return the last string that contains the search term
5313 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005314 num: return the number of times that the searchTerm appears in the log
5315 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005316 """
5317 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005318 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005319 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005320 logPath = '/opt/onos/log/karaf.log.'
5321 logPaths = '/opt/onos/log/karaf.log'
5322 for i in range( 1, logNum ):
5323 logPaths = logPath + str( i ) + " " + logPaths
5324 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005325 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005326 # 100000000 is just a extreme large number to make sure this function can
5327 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005328 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005329 if mode == 'all':
5330 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005331 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005332 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005333 elif mode == 'first':
5334 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5335 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005336 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005337 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005338 return num
You Wang6d301d42017-04-21 10:49:33 -07005339 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005340 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005341 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005342 else:
5343 main.log.error( self.name + " unsupported mode" )
5344 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005345 before = self.sendline( cmd )
5346 before = before.splitlines()
5347 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005348 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005349 return returnLines
5350 except AssertionError:
5351 main.log.error( self.name + " searchTerm is not string type" )
5352 return None
5353 except pexpect.EOF:
5354 main.log.error( self.name + ": EOF exception found" )
5355 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005356 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005357 except pexpect.TIMEOUT:
5358 main.log.error( self.name + ": TIMEOUT exception found" )
5359 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005360 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005361 except Exception:
5362 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005363 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005364
5365 def vplsShow( self, jsonFormat=True ):
5366 """
5367 Description: Returns result of onos:vpls show, which should list the
5368 configured VPLS networks and the assigned interfaces.
5369 Optional:
5370 * jsonFormat: enable json formatting of output
5371 Returns:
5372 The output of the command or None on error.
5373 """
5374 try:
5375 cmdStr = "vpls show"
5376 if jsonFormat:
5377 raise NotImplementedError
5378 cmdStr += " -j"
5379 handle = self.sendline( cmdStr )
5380 assert handle is not None, "Error in sendline"
5381 assert "Command not found:" not in handle, handle
5382 return handle
5383 except AssertionError:
5384 main.log.exception( "" )
5385 return None
5386 except TypeError:
5387 main.log.exception( self.name + ": Object not as expected" )
5388 return None
5389 except pexpect.EOF:
5390 main.log.error( self.name + ": EOF exception found" )
5391 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005392 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005393 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005394 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005395 return None
5396 except Exception:
5397 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005398 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005399
5400 def parseVplsShow( self ):
5401 """
5402 Parse the cli output of 'vpls show' into json output. This is required
5403 as there is currently no json output available.
5404 """
5405 try:
5406 output = []
5407 raw = self.vplsShow( jsonFormat=False )
5408 namePat = "VPLS name: (?P<name>\w+)"
5409 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5410 encapPat = "Encapsulation: (?P<encap>\w+)"
5411 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5412 mIter = re.finditer( pattern, raw )
5413 for match in mIter:
5414 item = {}
5415 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005416 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005417 if ifaces == [ "" ]:
5418 ifaces = []
5419 item[ 'interfaces' ] = ifaces
5420 encap = match.group( 'encap' )
5421 if encap != 'NONE':
5422 item[ 'encapsulation' ] = encap.lower()
5423 output.append( item )
5424 return output
5425 except Exception:
5426 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005427 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005428
5429 def vplsList( self, jsonFormat=True ):
5430 """
5431 Description: Returns result of onos:vpls list, which should list the
5432 configured VPLS networks.
5433 Optional:
5434 * jsonFormat: enable json formatting of output
5435 """
5436 try:
5437 cmdStr = "vpls list"
5438 if jsonFormat:
5439 raise NotImplementedError
5440 cmdStr += " -j"
5441 handle = self.sendline( cmdStr )
5442 assert handle is not None, "Error in sendline"
5443 assert "Command not found:" not in handle, handle
5444 return handle
5445 except AssertionError:
5446 main.log.exception( "" )
5447 return None
5448 except TypeError:
5449 main.log.exception( self.name + ": Object not as expected" )
5450 return None
5451 except pexpect.EOF:
5452 main.log.error( self.name + ": EOF exception found" )
5453 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005454 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005455 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005456 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005457 return None
5458 except Exception:
5459 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005460 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005461
5462 def vplsCreate( self, network ):
5463 """
5464 CLI command to create a new VPLS network.
5465 Required arguments:
5466 network - String name of the network to create.
5467 returns:
5468 main.TRUE on success and main.FALSE on failure
5469 """
5470 try:
5471 network = str( network )
5472 cmdStr = "vpls create "
5473 cmdStr += network
5474 output = self.sendline( cmdStr )
5475 assert output is not None, "Error in sendline"
5476 assert "Command not found:" not in output, output
5477 assert "Error executing command" not in output, output
5478 assert "VPLS already exists:" not in output, output
5479 return main.TRUE
5480 except AssertionError:
5481 main.log.exception( "" )
5482 return main.FALSE
5483 except TypeError:
5484 main.log.exception( self.name + ": Object not as expected" )
5485 return main.FALSE
5486 except pexpect.EOF:
5487 main.log.error( self.name + ": EOF exception found" )
5488 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005489 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005490 except Exception:
5491 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005492 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005493
5494 def vplsDelete( self, network ):
5495 """
5496 CLI command to delete a VPLS network.
5497 Required arguments:
5498 network - Name of the network to delete.
5499 returns:
5500 main.TRUE on success and main.FALSE on failure
5501 """
5502 try:
5503 network = str( network )
5504 cmdStr = "vpls delete "
5505 cmdStr += network
5506 output = self.sendline( cmdStr )
5507 assert output is not None, "Error in sendline"
5508 assert "Command not found:" not in output, output
5509 assert "Error executing command" not in output, output
5510 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005511 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005512 return main.TRUE
5513 except AssertionError:
5514 main.log.exception( "" )
5515 return main.FALSE
5516 except TypeError:
5517 main.log.exception( self.name + ": Object not as expected" )
5518 return main.FALSE
5519 except pexpect.EOF:
5520 main.log.error( self.name + ": EOF exception found" )
5521 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005522 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005523 except Exception:
5524 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005525 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005526
5527 def vplsAddIface( self, network, iface ):
5528 """
5529 CLI command to add an interface to a VPLS network.
5530 Required arguments:
5531 network - Name of the network to add the interface to.
5532 iface - The ONOS name for an interface.
5533 returns:
5534 main.TRUE on success and main.FALSE on failure
5535 """
5536 try:
5537 network = str( network )
5538 iface = str( iface )
5539 cmdStr = "vpls add-if "
5540 cmdStr += network + " " + iface
5541 output = self.sendline( cmdStr )
5542 assert output is not None, "Error in sendline"
5543 assert "Command not found:" not in output, output
5544 assert "Error executing command" not in output, output
5545 assert "already associated to network" not in output, output
5546 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005547 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005548 return main.TRUE
5549 except AssertionError:
5550 main.log.exception( "" )
5551 return main.FALSE
5552 except TypeError:
5553 main.log.exception( self.name + ": Object not as expected" )
5554 return main.FALSE
5555 except pexpect.EOF:
5556 main.log.error( self.name + ": EOF exception found" )
5557 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005558 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005559 except Exception:
5560 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005561 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005562
5563 def vplsRemIface( self, network, iface ):
5564 """
5565 CLI command to remove an interface from a VPLS network.
5566 Required arguments:
5567 network - Name of the network to remove the interface from.
5568 iface - Name of the interface to remove.
5569 returns:
5570 main.TRUE on success and main.FALSE on failure
5571 """
5572 try:
5573 iface = str( iface )
5574 cmdStr = "vpls rem-if "
5575 cmdStr += network + " " + iface
5576 output = self.sendline( cmdStr )
5577 assert output is not None, "Error in sendline"
5578 assert "Command not found:" not in output, output
5579 assert "Error executing command" not in output, output
5580 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005581 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005582 return main.TRUE
5583 except AssertionError:
5584 main.log.exception( "" )
5585 return main.FALSE
5586 except TypeError:
5587 main.log.exception( self.name + ": Object not as expected" )
5588 return main.FALSE
5589 except pexpect.EOF:
5590 main.log.error( self.name + ": EOF exception found" )
5591 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005592 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005593 except Exception:
5594 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005595 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005596
5597 def vplsClean( self ):
5598 """
5599 Description: Clears the VPLS app configuration.
5600 Returns: main.TRUE on success and main.FALSE on failure
5601 """
5602 try:
5603 cmdStr = "vpls clean"
5604 handle = self.sendline( cmdStr )
5605 assert handle is not None, "Error in sendline"
5606 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005607 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005608 return handle
5609 except AssertionError:
5610 main.log.exception( "" )
5611 return main.FALSE
5612 except TypeError:
5613 main.log.exception( self.name + ": Object not as expected" )
5614 return main.FALSE
5615 except pexpect.EOF:
5616 main.log.error( self.name + ": EOF exception found" )
5617 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005618 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005619 except Exception:
5620 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005621 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005622
5623 def vplsSetEncap( self, network, encapType ):
5624 """
5625 CLI command to add an interface to a VPLS network.
5626 Required arguments:
5627 network - Name of the network to create.
5628 encapType - Type of encapsulation.
5629 returns:
5630 main.TRUE on success and main.FALSE on failure
5631 """
5632 try:
5633 network = str( network )
5634 encapType = str( encapType ).upper()
5635 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5636 cmdStr = "vpls set-encap "
5637 cmdStr += network + " " + encapType
5638 output = self.sendline( cmdStr )
5639 assert output is not None, "Error in sendline"
5640 assert "Command not found:" not in output, output
5641 assert "Error executing command" not in output, output
5642 assert "already associated to network" not in output, output
5643 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005644 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005645 return main.TRUE
5646 except AssertionError:
5647 main.log.exception( "" )
5648 return main.FALSE
5649 except TypeError:
5650 main.log.exception( self.name + ": Object not as expected" )
5651 return main.FALSE
5652 except pexpect.EOF:
5653 main.log.error( self.name + ": EOF exception found" )
5654 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005655 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005656 except Exception:
5657 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005658 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005659
5660 def interfaces( self, jsonFormat=True ):
5661 """
5662 Description: Returns result of interfaces command.
5663 Optional:
5664 * jsonFormat: enable json formatting of output
5665 Returns:
5666 The output of the command or None on error.
5667 """
5668 try:
5669 cmdStr = "interfaces"
5670 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005671 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005672 cmdStr += " -j"
5673 handle = self.sendline( cmdStr )
5674 assert handle is not None, "Error in sendline"
5675 assert "Command not found:" not in handle, handle
5676 return handle
5677 except AssertionError:
5678 main.log.exception( "" )
5679 return None
5680 except TypeError:
5681 main.log.exception( self.name + ": Object not as expected" )
5682 return None
5683 except pexpect.EOF:
5684 main.log.error( self.name + ": EOF exception found" )
5685 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005686 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005687 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005688 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005689 return None
5690 except Exception:
5691 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005692 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005693
5694 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005695 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005696 Get the timestamp of searchTerm from karaf log.
5697
5698 Arguments:
5699 splitTerm_before and splitTerm_after:
5700
5701 The terms that split the string that contains the timeStamp of
5702 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5703 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5704 and the splitTerm_after is "x"
5705
5706 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005707 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005708 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005709 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005710 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005711 return main.ERROR
5712 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005713 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005714 main.log.warn( "Captured timestamp string is empty" )
5715 return main.ERROR
5716 lines = lines[ 0 ]
5717 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005718 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005719 # get the target value
5720 line = lines.split( splitTerm_before )
5721 key = line[ 1 ].split( splitTerm_after )
5722 return int( key[ 0 ] )
5723 except IndexError:
5724 main.log.warn( "Index Error!" )
5725 return main.ERROR
5726 except AssertionError:
5727 main.log.warn( "Search Term Not Found " )
5728 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005729
5730 def workQueueAdd( self, queueName, value ):
5731 """
5732 CLI command to add a string to the specified Work Queue.
5733 This function uses the distributed primitives test app, which
5734 gives some cli access to distributed primitives for testing
5735 purposes only.
5736
5737 Required arguments:
5738 queueName - The name of the queue to add to
5739 value - The value to add to the queue
5740 returns:
5741 main.TRUE on success, main.FALSE on failure and
5742 main.ERROR on error.
5743 """
5744 try:
5745 queueName = str( queueName )
5746 value = str( value )
5747 prefix = "work-queue-test"
5748 operation = "add"
5749 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5750 output = self.distPrimitivesSend( cmdStr )
5751 if "Invalid operation name" in output:
5752 main.log.warn( output )
5753 return main.ERROR
5754 elif "Done" in output:
5755 return main.TRUE
5756 except TypeError:
5757 main.log.exception( self.name + ": Object not as expected" )
5758 return main.ERROR
5759 except Exception:
5760 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005761 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005762
5763 def workQueueAddMultiple( self, queueName, value1, value2 ):
5764 """
5765 CLI command to add two strings to the specified Work Queue.
5766 This function uses the distributed primitives test app, which
5767 gives some cli access to distributed primitives for testing
5768 purposes only.
5769
5770 Required arguments:
5771 queueName - The name of the queue to add to
5772 value1 - The first value to add to the queue
5773 value2 - The second value to add to the queue
5774 returns:
5775 main.TRUE on success, main.FALSE on failure and
5776 main.ERROR on error.
5777 """
5778 try:
5779 queueName = str( queueName )
5780 value1 = str( value1 )
5781 value2 = str( value2 )
5782 prefix = "work-queue-test"
5783 operation = "addMultiple"
5784 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5785 output = self.distPrimitivesSend( cmdStr )
5786 if "Invalid operation name" in output:
5787 main.log.warn( output )
5788 return main.ERROR
5789 elif "Done" in output:
5790 return main.TRUE
5791 except TypeError:
5792 main.log.exception( self.name + ": Object not as expected" )
5793 return main.ERROR
5794 except Exception:
5795 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005796 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005797
5798 def workQueueTakeAndComplete( self, queueName, number=1 ):
5799 """
5800 CLI command to take a value from the specified Work Queue and compelte it.
5801 This function uses the distributed primitives test app, which
5802 gives some cli access to distributed primitives for testing
5803 purposes only.
5804
5805 Required arguments:
5806 queueName - The name of the queue to add to
5807 number - The number of items to take and complete
5808 returns:
5809 main.TRUE on success, main.FALSE on failure and
5810 main.ERROR on error.
5811 """
5812 try:
5813 queueName = str( queueName )
5814 number = str( int( number ) )
5815 prefix = "work-queue-test"
5816 operation = "takeAndComplete"
5817 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5818 output = self.distPrimitivesSend( cmdStr )
5819 if "Invalid operation name" in output:
5820 main.log.warn( output )
5821 return main.ERROR
5822 elif "Done" in output:
5823 return main.TRUE
5824 except TypeError:
5825 main.log.exception( self.name + ": Object not as expected" )
5826 return main.ERROR
5827 except Exception:
5828 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005829 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005830
5831 def workQueueDestroy( self, queueName ):
5832 """
5833 CLI command to destroy the specified Work Queue.
5834 This function uses the distributed primitives test app, which
5835 gives some cli access to distributed primitives for testing
5836 purposes only.
5837
5838 Required arguments:
5839 queueName - The name of the queue to add to
5840 returns:
5841 main.TRUE on success, main.FALSE on failure and
5842 main.ERROR on error.
5843 """
5844 try:
5845 queueName = str( queueName )
5846 prefix = "work-queue-test"
5847 operation = "destroy"
5848 cmdStr = " ".join( [ prefix, queueName, operation ] )
5849 output = self.distPrimitivesSend( cmdStr )
5850 if "Invalid operation name" in output:
5851 main.log.warn( output )
5852 return main.ERROR
5853 return main.TRUE
5854 except TypeError:
5855 main.log.exception( self.name + ": Object not as expected" )
5856 return main.ERROR
5857 except Exception:
5858 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005859 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005860
5861 def workQueueTotalPending( self, queueName ):
5862 """
5863 CLI command to get the Total Pending items of the specified Work Queue.
5864 This function uses the distributed primitives test app, which
5865 gives some cli access to distributed primitives for testing
5866 purposes only.
5867
5868 Required arguments:
5869 queueName - The name of the queue to add to
5870 returns:
5871 The number of Pending items in the specified work queue or
5872 None on error
5873 """
5874 try:
5875 queueName = str( queueName )
5876 prefix = "work-queue-test"
5877 operation = "totalPending"
5878 cmdStr = " ".join( [ prefix, queueName, operation ] )
5879 output = self.distPrimitivesSend( cmdStr )
5880 pattern = r'\d+'
5881 if "Invalid operation name" in output:
5882 main.log.warn( output )
5883 return None
5884 else:
5885 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005886 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005887 except ( AttributeError, TypeError ):
5888 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5889 return None
5890 except Exception:
5891 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005892 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005893
5894 def workQueueTotalCompleted( self, queueName ):
5895 """
5896 CLI command to get the Total Completed items of the specified Work Queue.
5897 This function uses the distributed primitives test app, which
5898 gives some cli access to distributed primitives for testing
5899 purposes only.
5900
5901 Required arguments:
5902 queueName - The name of the queue to add to
5903 returns:
5904 The number of complete items in the specified work queue or
5905 None on error
5906 """
5907 try:
5908 queueName = str( queueName )
5909 prefix = "work-queue-test"
5910 operation = "totalCompleted"
5911 cmdStr = " ".join( [ prefix, queueName, operation ] )
5912 output = self.distPrimitivesSend( cmdStr )
5913 pattern = r'\d+'
5914 if "Invalid operation name" in output:
5915 main.log.warn( output )
5916 return None
5917 else:
5918 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005919 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005920 except ( AttributeError, TypeError ):
5921 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5922 return None
5923 except Exception:
5924 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005925 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005926
5927 def workQueueTotalInProgress( self, queueName ):
5928 """
5929 CLI command to get the Total In Progress items of the specified Work Queue.
5930 This function uses the distributed primitives test app, which
5931 gives some cli access to distributed primitives for testing
5932 purposes only.
5933
5934 Required arguments:
5935 queueName - The name of the queue to add to
5936 returns:
5937 The number of In Progress items in the specified work queue or
5938 None on error
5939 """
5940 try:
5941 queueName = str( queueName )
5942 prefix = "work-queue-test"
5943 operation = "totalInProgress"
5944 cmdStr = " ".join( [ prefix, queueName, operation ] )
5945 output = self.distPrimitivesSend( cmdStr )
5946 pattern = r'\d+'
5947 if "Invalid operation name" in output:
5948 main.log.warn( output )
5949 return None
5950 else:
5951 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005952 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005953 except ( AttributeError, TypeError ):
5954 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5955 return None
5956 except Exception:
5957 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005958 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005959
5960 def events( self, args='-a' ):
5961 """
5962 Description: Returns events -a command output
5963 Optional:
5964 add other arguments
5965 """
5966 try:
5967 cmdStr = "events"
5968 if args:
5969 cmdStr += " " + args
5970 handle = self.sendline( cmdStr )
5971 assert handle is not None, "Error in sendline"
5972 assert "Command not found:" not in handle, handle
5973 return handle
5974 except AssertionError:
5975 main.log.exception( "" )
5976 return None
5977 except TypeError:
5978 main.log.exception( self.name + ": Object not as expected" )
5979 return None
5980 except pexpect.EOF:
5981 main.log.error( self.name + ": EOF exception found" )
5982 main.log.error( self.name + ": " + self.handle.before )
5983 main.cleanAndExit()
5984 except Exception:
5985 main.log.exception( self.name + ": Uncaught exception!" )
5986 main.cleanAndExit()
5987
5988 def getMaster( self, deviceID ):
5989 """
5990 Description: Obtains current master using "roles" command for a specific deviceID
5991 """
5992 try:
5993 return str( self.getRole( deviceID )[ 'master' ] )
5994 except AssertionError:
5995 main.log.exception( "" )
5996 return None
5997 except TypeError:
5998 main.log.exception( self.name + ": Object not as expected" )
5999 return None
6000 except pexpect.EOF:
6001 main.log.error( self.name + ": EOF exception found" )
6002 main.log.error( self.name + ": " + self.handle.before )
6003 main.cleanAndExit()
6004 except Exception:
6005 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07006006 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08006007
6008 def issu( self ):
6009 """
6010 Short summary of In-Service Software Upgrade status
6011
6012 Returns the output of the cli command or None on Error
6013 """
6014 try:
6015 cmdStr = "issu"
6016 handle = self.sendline( cmdStr )
6017 assert handle is not None, "Error in sendline"
6018 assert "Command not found:" not in handle, handle
6019 assert "Unsupported command:" not in handle, handle
6020 return handle
6021 except AssertionError:
6022 main.log.exception( "" )
6023 return None
6024 except TypeError:
6025 main.log.exception( self.name + ": Object not as expected" )
6026 return None
6027 except pexpect.EOF:
6028 main.log.error( self.name + ": EOF exception found" )
6029 main.log.error( self.name + ": " + self.handle.before )
6030 main.cleanAndExit()
6031 except Exception:
6032 main.log.exception( self.name + ": Uncaught exception!" )
6033 main.cleanAndExit()
6034
6035 def issuInit( self ):
6036 """
6037 Initiates an In-Service Software Upgrade
6038
6039 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6040 """
6041 try:
6042 cmdStr = "issu init"
6043 handle = self.sendline( cmdStr )
6044 assert handle is not None, "Error in sendline"
6045 assert "Command not found:" not in handle, handle
6046 assert "Unsupported command:" not in handle, handle
6047 if "Initialized" in handle:
6048 return main.TRUE
6049 else:
6050 return main.FALSE
6051 except AssertionError:
6052 main.log.exception( "" )
6053 return main.ERROR
6054 except TypeError:
6055 main.log.exception( self.name + ": Object not as expected" )
6056 return main.ERROR
6057 except pexpect.EOF:
6058 main.log.error( self.name + ": EOF exception found" )
6059 main.log.error( self.name + ": " + self.handle.before )
6060 main.cleanAndExit()
6061 except Exception:
6062 main.log.exception( self.name + ": Uncaught exception!" )
6063 main.cleanAndExit()
6064
6065 def issuUpgrade( self ):
6066 """
6067 Transitions stores to upgraded nodes
6068
6069 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6070 """
6071 try:
6072 cmdStr = "issu upgrade"
6073 handle = self.sendline( cmdStr )
6074 assert handle is not None, "Error in sendline"
6075 assert "Command not found:" not in handle, handle
6076 assert "Unsupported command:" not in handle, handle
6077 if "Upgraded" in handle:
6078 return main.TRUE
6079 else:
6080 return main.FALSE
6081 except AssertionError:
6082 main.log.exception( "" )
6083 return main.ERROR
6084 except TypeError:
6085 main.log.exception( self.name + ": Object not as expected" )
6086 return main.ERROR
6087 except pexpect.EOF:
6088 main.log.error( self.name + ": EOF exception found" )
6089 main.log.error( self.name + ": " + self.handle.before )
6090 main.cleanAndExit()
6091 except Exception:
6092 main.log.exception( self.name + ": Uncaught exception!" )
6093 main.cleanAndExit()
6094
6095 def issuCommit( self ):
6096 """
6097 Finalizes an In-Service Software Upgrade
6098
6099 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6100 """
6101 try:
6102 cmdStr = "issu commit"
6103 handle = self.sendline( cmdStr )
6104 assert handle is not None, "Error in sendline"
6105 assert "Command not found:" not in handle, handle
6106 assert "Unsupported command:" not in handle, handle
6107 # TODO: Check the version returned by this command
6108 if "Committed version" in handle:
6109 return main.TRUE
6110 else:
6111 return main.FALSE
6112 except AssertionError:
6113 main.log.exception( "" )
6114 return main.ERROR
6115 except TypeError:
6116 main.log.exception( self.name + ": Object not as expected" )
6117 return main.ERROR
6118 except pexpect.EOF:
6119 main.log.error( self.name + ": EOF exception found" )
6120 main.log.error( self.name + ": " + self.handle.before )
6121 main.cleanAndExit()
6122 except Exception:
6123 main.log.exception( self.name + ": Uncaught exception!" )
6124 main.cleanAndExit()
6125
6126 def issuRollback( self ):
6127 """
6128 Rolls back an In-Service Software Upgrade
6129
6130 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6131 """
6132 try:
6133 cmdStr = "issu rollback"
6134 handle = self.sendline( cmdStr )
6135 assert handle is not None, "Error in sendline"
6136 assert "Command not found:" not in handle, handle
6137 assert "Unsupported command:" not in handle, handle
6138 # TODO: Check the version returned by this command
6139 if "Rolled back to version" in handle:
6140 return main.TRUE
6141 else:
6142 return main.FALSE
6143 except AssertionError:
6144 main.log.exception( "" )
6145 return main.ERROR
6146 except TypeError:
6147 main.log.exception( self.name + ": Object not as expected" )
6148 return main.ERROR
6149 except pexpect.EOF:
6150 main.log.error( self.name + ": EOF exception found" )
6151 main.log.error( self.name + ": " + self.handle.before )
6152 main.cleanAndExit()
6153 except Exception:
6154 main.log.exception( self.name + ": Uncaught exception!" )
6155 main.cleanAndExit()
6156
6157 def issuReset( self ):
6158 """
6159 Resets the In-Service Software Upgrade status after a rollback
6160
6161 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6162 """
6163 try:
6164 cmdStr = "issu reset"
6165 handle = self.sendline( cmdStr )
6166 assert handle is not None, "Error in sendline"
6167 assert "Command not found:" not in handle, handle
6168 assert "Unsupported command:" not in handle, handle
6169 # TODO: Check the version returned by this command
6170 if "Reset version" in handle:
6171 return main.TRUE
6172 else:
6173 return main.FALSE
6174 except AssertionError:
6175 main.log.exception( "" )
6176 return main.ERROR
6177 except TypeError:
6178 main.log.exception( self.name + ": Object not as expected" )
6179 return main.ERROR
6180 except pexpect.EOF:
6181 main.log.error( self.name + ": EOF exception found" )
6182 main.log.error( self.name + ": " + self.handle.before )
6183 main.cleanAndExit()
6184 except Exception:
6185 main.log.exception( self.name + ": Uncaught exception!" )
6186 main.cleanAndExit()
6187
6188 def issuStatus( self ):
6189 """
6190 Status of an In-Service Software Upgrade
6191
6192 Returns the output of the cli command or None on Error
6193 """
6194 try:
6195 cmdStr = "issu status"
6196 handle = self.sendline( cmdStr )
6197 assert handle is not None, "Error in sendline"
6198 assert "Command not found:" not in handle, handle
6199 assert "Unsupported command:" not in handle, handle
6200 return handle
6201 except AssertionError:
6202 main.log.exception( "" )
6203 return None
6204 except TypeError:
6205 main.log.exception( self.name + ": Object not as expected" )
6206 return None
6207 except pexpect.EOF:
6208 main.log.error( self.name + ": EOF exception found" )
6209 main.log.error( self.name + ": " + self.handle.before )
6210 main.cleanAndExit()
6211 except Exception:
6212 main.log.exception( self.name + ": Uncaught exception!" )
6213 main.cleanAndExit()
6214
6215 def issuVersion( self ):
6216 """
6217 Get the version of an In-Service Software Upgrade
6218
6219 Returns the output of the cli command or None on Error
6220 """
6221 try:
6222 cmdStr = "issu version"
6223 handle = self.sendline( cmdStr )
6224 assert handle is not None, "Error in sendline"
6225 assert "Command not found:" not in handle, handle
6226 assert "Unsupported command:" not in handle, handle
6227 return handle
6228 except AssertionError:
6229 main.log.exception( "" )
6230 return None
6231 except TypeError:
6232 main.log.exception( self.name + ": Object not as expected" )
6233 return None
6234 except pexpect.EOF:
6235 main.log.error( self.name + ": EOF exception found" )
6236 main.log.error( self.name + ": " + self.handle.before )
6237 main.cleanAndExit()
6238 except Exception:
6239 main.log.exception( self.name + ": Uncaught exception!" )
6240 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006241
6242 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6243 """
6244 Create a multicast route by calling 'mcast-join' command
6245 sIP: source IP of the multicast route
6246 groupIP: group IP of the multicast route
6247 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6248 dPorts: a list of destination ports of the multicast route
6249 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6250 """
6251 try:
6252 cmdStr = "mcast-join"
6253 cmdStr += " " + str( sIP )
6254 cmdStr += " " + str( groupIP )
6255 cmdStr += " " + str( sPort )
6256 assert isinstance( dPorts, list )
6257 for dPort in dPorts:
6258 cmdStr += " " + str( dPort )
6259 handle = self.sendline( cmdStr )
6260 assert handle is not None, "Error in sendline"
6261 assert "Command not found:" not in handle, handle
6262 assert "Unsupported command:" not in handle, handle
6263 assert "Error executing command" not in handle, handle
6264 if "Added the mcast route" in handle:
6265 return main.TRUE
6266 else:
6267 return main.FALSE
6268 except AssertionError:
6269 main.log.exception( "" )
6270 return None
6271 except TypeError:
6272 main.log.exception( self.name + ": Object not as expected" )
6273 return None
6274 except pexpect.EOF:
6275 main.log.error( self.name + ": EOF exception found" )
6276 main.log.error( self.name + ": " + self.handle.before )
6277 main.cleanAndExit()
6278 except Exception:
6279 main.log.exception( self.name + ": Uncaught exception!" )
6280 main.cleanAndExit()
6281
6282 def mcastDelete( self, sIP, groupIP, dPorts ):
6283 """
6284 Delete a multicast route by calling 'mcast-delete' command
6285 sIP: source IP of the multicast route
6286 groupIP: group IP of the multicast route
6287 dPorts: a list of destination ports of the multicast route
6288 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6289 """
6290 try:
6291 cmdStr = "mcast-delete"
6292 cmdStr += " " + str( sIP )
6293 cmdStr += " " + str( groupIP )
6294 assert isinstance( dPorts, list )
6295 for dPort in dPorts:
6296 cmdStr += " " + str( dPort )
6297 handle = self.sendline( cmdStr )
6298 assert handle is not None, "Error in sendline"
6299 assert "Command not found:" not in handle, handle
6300 assert "Unsupported command:" not in handle, handle
6301 assert "Error executing command" not in handle, handle
6302 if "Updated the mcast route" in handle:
6303 return main.TRUE
6304 else:
6305 return main.FALSE
6306 except AssertionError:
6307 main.log.exception( "" )
6308 return None
6309 except TypeError:
6310 main.log.exception( self.name + ": Object not as expected" )
6311 return None
6312 except pexpect.EOF:
6313 main.log.error( self.name + ": EOF exception found" )
6314 main.log.error( self.name + ": " + self.handle.before )
6315 main.cleanAndExit()
6316 except Exception:
6317 main.log.exception( self.name + ": Uncaught exception!" )
6318 main.cleanAndExit()
6319
6320 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6321 """
6322 Create a multicast route by calling 'mcast-host-join' command
6323 sAddr: we can provide * for ASM or a specific address for SSM
6324 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006325 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006326 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6327 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6328 """
6329 try:
6330 cmdStr = "mcast-host-join"
6331 cmdStr += " -sAddr " + str( sAddr )
6332 cmdStr += " -gAddr " + str( gAddr )
6333 assert isinstance( srcs, list )
6334 for src in srcs:
6335 cmdStr += " -srcs " + str( src )
6336 assert isinstance( sinks, list )
6337 for sink in sinks:
6338 cmdStr += " -sinks " + str( sink )
6339 handle = self.sendline( cmdStr )
6340 assert handle is not None, "Error in sendline"
6341 assert "Command not found:" not in handle, handle
6342 assert "Unsupported command:" not in handle, handle
6343 assert "Error executing command" not in handle, handle
6344 if "Added the mcast route" in handle:
6345 return main.TRUE
6346 else:
6347 return main.FALSE
6348 except AssertionError:
6349 main.log.exception( "" )
6350 return None
6351 except TypeError:
6352 main.log.exception( self.name + ": Object not as expected" )
6353 return None
6354 except pexpect.EOF:
6355 main.log.error( self.name + ": EOF exception found" )
6356 main.log.error( self.name + ": " + self.handle.before )
6357 main.cleanAndExit()
6358 except Exception:
6359 main.log.exception( self.name + ": Uncaught exception!" )
6360 main.cleanAndExit()
6361
6362 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6363 """
6364 Delete multicast sink(s) by calling 'mcast-host-delete' command
6365 sAddr: we can provide * for ASM or a specific address for SSM
6366 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006367 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006368 will delete the route if not specified
6369 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6370 """
6371 try:
6372 cmdStr = "mcast-host-delete"
6373 cmdStr += " -sAddr " + str( sAddr )
6374 cmdStr += " -gAddr " + str( gAddr )
6375 if host:
6376 cmdStr += " -h " + str( host )
6377 handle = self.sendline( cmdStr )
6378 assert handle is not None, "Error in sendline"
6379 assert "Command not found:" not in handle, handle
6380 assert "Unsupported command:" not in handle, handle
6381 assert "Error executing command" not in handle, handle
6382 if "Updated the mcast route" in handle:
6383 return main.TRUE
6384 elif "Deleted the mcast route" in handle:
6385 return main.TRUE
6386 else:
6387 return main.FALSE
6388 except AssertionError:
6389 main.log.exception( "" )
6390 return None
6391 except TypeError:
6392 main.log.exception( self.name + ": Object not as expected" )
6393 return None
6394 except pexpect.EOF:
6395 main.log.error( self.name + ": EOF exception found" )
6396 main.log.error( self.name + ": " + self.handle.before )
6397 main.cleanAndExit()
6398 except Exception:
6399 main.log.exception( self.name + ": Uncaught exception!" )
6400 main.cleanAndExit()
6401
You Wang547893e2018-05-08 13:34:59 -07006402 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6403 """
6404 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6405 sAddr: we can provide * for ASM or a specific address for SSM
6406 gAddr: specifies multicast group address
6407 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6408 will delete the route if not specified
6409 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6410 """
6411 try:
6412 cmdStr = "mcast-sink-delete"
6413 cmdStr += " -sAddr " + str( sAddr )
6414 cmdStr += " -gAddr " + str( gAddr )
6415 if sink:
6416 cmdStr += " -s " + str( sink )
6417 handle = self.sendline( cmdStr )
6418 assert handle is not None, "Error in sendline"
6419 assert "Command not found:" not in handle, handle
6420 assert "Unsupported command:" not in handle, handle
6421 assert "Error executing command" not in handle, handle
6422 if "Updated the mcast route" in handle:
6423 return main.TRUE
6424 elif "Deleted the mcast route" in handle:
6425 return main.TRUE
6426 else:
6427 return main.FALSE
6428 except AssertionError:
6429 main.log.exception( "" )
6430 return None
6431 except TypeError:
6432 main.log.exception( self.name + ": Object not as expected" )
6433 return None
6434 except pexpect.EOF:
6435 main.log.error( self.name + ": EOF exception found" )
6436 main.log.error( self.name + ": " + self.handle.before )
6437 main.cleanAndExit()
6438 except Exception:
6439 main.log.exception( self.name + ": Uncaught exception!" )
6440 main.cleanAndExit()
6441
You Wange24d6272018-03-27 21:18:50 -07006442 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6443 """
6444 Delete multicast src(s) by calling 'mcast-source-delete' command
6445 sAddr: we can provide * for ASM or a specific address for SSM
6446 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006447 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 -07006448 will delete the route if not specified
6449 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6450 """
6451 try:
6452 cmdStr = "mcast-source-delete"
6453 cmdStr += " -sAddr " + str( sAddr )
6454 cmdStr += " -gAddr " + str( gAddr )
6455 if srcs:
6456 assert isinstance( srcs, list )
6457 for src in srcs:
6458 cmdStr += " -src " + str( src )
6459 handle = self.sendline( cmdStr )
6460 assert handle is not None, "Error in sendline"
6461 assert "Command not found:" not in handle, handle
6462 assert "Unsupported command:" not in handle, handle
6463 assert "Error executing command" not in handle, handle
6464 if "Updated the mcast route" in handle:
6465 return main.TRUE
6466 elif "Deleted the mcast route" in handle:
6467 return main.TRUE
6468 else:
6469 return main.FALSE
6470 except AssertionError:
6471 main.log.exception( "" )
6472 return None
6473 except TypeError:
6474 main.log.exception( self.name + ": Object not as expected" )
6475 return None
6476 except pexpect.EOF:
6477 main.log.error( self.name + ": EOF exception found" )
6478 main.log.error( self.name + ": " + self.handle.before )
6479 main.cleanAndExit()
6480 except Exception:
6481 main.log.exception( self.name + ": Uncaught exception!" )
6482 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006483
6484 def netcfg( self, jsonFormat=True, args="" ):
6485 """
6486 Run netcfg cli command with given args
6487 """
6488 try:
6489 cmdStr = "netcfg"
6490 if jsonFormat:
6491 cmdStr = cmdStr + " -j"
6492 if args:
6493 cmdStr = cmdStr + " " + str( args )
6494 handle = self.sendline( cmdStr )
6495 assert handle is not None, "Error in sendline"
6496 assert "Command not found:" not in handle, handle
6497 assert "Unsupported command:" not in handle, handle
6498 assert "Error executing command" not in handle, handle
6499 return handle
6500 except AssertionError:
6501 main.log.exception( "" )
6502 return None
6503 except TypeError:
6504 main.log.exception( self.name + ": Object not as expected" )
6505 return None
6506 except pexpect.EOF:
6507 main.log.error( self.name + ": EOF exception found" )
6508 main.log.error( self.name + ": " + self.handle.before )
6509 main.cleanAndExit()
6510 except Exception:
6511 main.log.exception( self.name + ": Uncaught exception!" )
6512 main.cleanAndExit()
6513
You Wang0fa76e72018-05-18 11:33:25 -07006514 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True, simple=False ):
You Wang5da39c82018-04-26 22:55:08 -07006515 """
You Wang54b1d672018-06-11 16:44:13 -07006516 Compose and return a list of t3-troubleshoot cli commands for given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006517 Options:
6518 sAddr: IP address of the source host
6519 dAddr: IP address of the destination host
You Wang0fa76e72018-05-18 11:33:25 -07006520 ipv6: True if hosts are IPv6
6521 verbose: return verbose t3 output if True
6522 simple: compose command for t3-troubleshoot-simple if True
You Wang5da39c82018-04-26 22:55:08 -07006523 """
6524 try:
6525 # Collect information of both hosts from onos
6526 hosts = self.hosts()
6527 hosts = json.loads( hosts )
6528 sHost = None
6529 dHost = None
6530 for host in hosts:
6531 if sAddr in host[ "ipAddresses" ]:
6532 sHost = host
6533 elif dAddr in host[ "ipAddresses" ]:
6534 dHost = host
6535 if sHost and dHost:
6536 break
6537 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang54b1d672018-06-11 16:44:13 -07006538 cmdList = []
You Wang5d9527b2018-05-29 17:08:54 -07006539 if simple:
6540 assert dHost, "Not able to find host with IP {}".format( dAddr )
You Wang54b1d672018-06-11 16:44:13 -07006541 cmdStr = "t3-troubleshoot-simple"
6542 if verbose:
6543 cmdStr += " -vv"
6544 if ipv6:
6545 cmdStr += " -et ipv6"
You Wang0fa76e72018-05-18 11:33:25 -07006546 cmdStr += " {}/{} {}/{}".format( sHost[ "mac" ], sHost[ "vlan" ], dHost[ "mac" ], dHost[ "vlan" ] )
You Wang54b1d672018-06-11 16:44:13 -07006547 cmdList.append( cmdStr )
You Wang0fa76e72018-05-18 11:33:25 -07006548 else:
You Wang54b1d672018-06-11 16:44:13 -07006549 for location in sHost[ "locations" ]:
6550 cmdStr = "t3-troubleshoot"
6551 if verbose:
6552 cmdStr += " -vv"
6553 if ipv6:
6554 cmdStr += " -et ipv6"
6555 cmdStr += " -s " + str( sAddr )
6556 cmdStr += " -sp " + str( location[ "elementId" ] ) + "/" + str( location[ "port" ] )
6557 cmdStr += " -sm " + str( sHost[ "mac" ] )
6558 if sHost[ "vlan" ] != "None":
6559 cmdStr += " -vid " + sHost[ "vlan" ]
6560 cmdStr += " -d " + str( dAddr )
6561 netcfg = self.netcfg( args="devices {}".format( location[ "elementId" ] ) )
6562 netcfg = json.loads( netcfg )
6563 assert netcfg, "Failed to get netcfg"
6564 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6565 cmdList.append( cmdStr )
6566 return cmdList
You Wang5da39c82018-04-26 22:55:08 -07006567 except AssertionError:
6568 main.log.exception( "" )
6569 return None
6570 except ( KeyError, TypeError ):
6571 main.log.exception( self.name + ": Object not as expected" )
6572 return None
6573 except Exception:
6574 main.log.exception( self.name + ": Uncaught exception!" )
6575 main.cleanAndExit()
6576
6577 def t3( self, sAddr, dAddr, ipv6=False ):
6578 """
You Wang54b1d672018-06-11 16:44:13 -07006579 Run t3-troubleshoot cli commands for all posible routes given source and destination addresses
You Wang5da39c82018-04-26 22:55:08 -07006580 Options:
6581 sAddr: IP address of the source host
6582 dAddr: IP address of the destination host
6583 """
6584 try:
You Wang54b1d672018-06-11 16:44:13 -07006585 cmdList = self.composeT3Command( sAddr, dAddr, ipv6 )
6586 assert cmdList is not None, "composeT3Command returned None"
6587 t3Output = ""
6588 for cmdStr in cmdList:
6589 handle = self.sendline( cmdStr )
6590 assert handle is not None, "Error in sendline"
6591 assert "Command not found:" not in handle, handle
6592 assert "Unsupported command:" not in handle, handle
6593 assert "Error executing command" not in handle, handle
6594 assert "Tracing packet" in handle
6595 t3Output += handle
6596 return t3Output
You Wang5da39c82018-04-26 22:55:08 -07006597 except AssertionError:
6598 main.log.exception( "" )
6599 return None
6600 except pexpect.EOF:
6601 main.log.error( self.name + ": EOF exception found" )
6602 main.log.error( self.name + ": " + self.handle.before )
6603 main.cleanAndExit()
6604 except Exception:
6605 main.log.exception( self.name + ": Uncaught exception!" )
6606 main.cleanAndExit()