blob: 439ba80a6165ff3c5e4627c477fc81e2f96e30c3 [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
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700463 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, dollarSign=False ):
kelvin8ec71442015-01-15 16:57:00 -0800464 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800465 Send a completely user specified string to
466 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400467 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800468
YPZhang14a4aa92016-07-15 13:37:15 -0700469 if noExit is True, TestON will not exit, and return None
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700470 if dollarSign is True, TestON will not expect for '$' as a new CLI or onos> prompt
471 since '$' can be in the output.
YPZhangebf9eb52016-05-12 15:20:24 -0700472
andrewonlaba18f6bf2014-10-13 19:31:54 -0400473 Warning: There are no sanity checking to commands
474 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800475
kelvin8ec71442015-01-15 16:57:00 -0800476 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400477 try:
Jon Halla495f562016-05-16 18:03:26 -0700478 # Try to reconnect if disconnected from cli
479 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700480 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ] )
Jon Halla495f562016-05-16 18:03:26 -0700481 if i == 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700482 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700483 if self.onosIp:
484 main.log.warn( "Trying to reconnect " + self.onosIp )
485 reconnectResult = self.startOnosCli( self.onosIp )
486 if reconnectResult:
487 main.log.info( self.name + ": onos cli session reconnected." )
488 else:
489 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700490 if noExit:
491 return None
492 else:
Devin Lim44075962017-08-11 10:56:37 -0700493 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700494 else:
Devin Lim44075962017-08-11 10:56:37 -0700495 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700496 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700497 main.log.warn( "Timeout when testing cli responsiveness" )
498 main.log.debug( self.handle.before )
499 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700500 self.handle.expect( "onos>" )
501
Jon Hall14a03b52016-05-11 12:07:30 -0700502 if debug:
503 # NOTE: This adds and average of .4 seconds per call
504 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700505 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 self.handle.sendline( cmdStr )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700507 if dollarSign:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700508 i = self.handle.expect( [ "onos>" ], timeout )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700509 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700510 i = self.handle.expect( [ "onos>", self.prompt ], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800511 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800512 # TODO: do something with i
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000513 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800514 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700515 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700516 main.log.debug( self.name + ": Raw output" )
517 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700518
519 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800520 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800521 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700522 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700523 main.log.debug( self.name + ": ansiEscape output" )
524 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700525
kelvin-onlabfb521662015-02-27 09:52:40 -0800526 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000527 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700528 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700529 main.log.debug( self.name + ": Removed extra returns " +
530 "from output" )
531 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700532
533 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800534 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700535 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700536 main.log.debug( self.name + ": parsed and stripped output" )
537 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700538
Jon Hall63604932015-02-26 17:09:50 -0800539 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700540 output = response.split( cmdStr.strip(), 1 )
541 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700542 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700543 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700544 main.log.debug( self.name + ": " + repr( r ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700545 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800546 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800547 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800548 return output
GlennRCed771242016-01-13 17:02:47 -0800549 except pexpect.TIMEOUT:
550 main.log.error( self.name + ":ONOS timeout" )
551 if debug:
552 main.log.debug( self.handle.before )
553 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700554 except IndexError:
555 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700556 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700557 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800558 except TypeError:
559 main.log.exception( self.name + ": Object not as expected" )
560 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400561 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800562 main.log.error( self.name + ": EOF exception found" )
563 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700564 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700565 return None
566 else:
Devin Lim44075962017-08-11 10:56:37 -0700567 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800568 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800569 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700570 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700571 return None
572 else:
Devin Lim44075962017-08-11 10:56:37 -0700573 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400574
kelvin8ec71442015-01-15 16:57:00 -0800575 # IMPORTANT NOTE:
576 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800577 # the cli command changing 'a:b' with 'aB'.
578 # Ex ) onos:topology > onosTopology
579 # onos:links > onosLinks
580 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800581
kelvin-onlabd3b64892015-01-20 13:26:24 -0800582 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800583 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400584 Adds a new cluster node by ID and address information.
585 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800586 * nodeId
587 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400588 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800589 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800590 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400591 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800592 cmdStr = "add-node " + str( nodeId ) + " " +\
593 str( ONOSIp ) + " " + str( tcpPort )
594 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700595 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800596 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800597 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800598 main.log.error( "Error in adding node" )
599 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800600 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400601 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400603 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800604 except AssertionError:
605 main.log.exception( "" )
606 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800607 except TypeError:
608 main.log.exception( self.name + ": Object not as expected" )
609 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400610 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800611 main.log.error( self.name + ": EOF exception found" )
612 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700613 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800614 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800615 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700616 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400617
kelvin-onlabd3b64892015-01-20 13:26:24 -0800618 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800619 """
andrewonlab86dc3082014-10-13 18:18:38 -0400620 Removes a cluster by ID
621 Issues command: 'remove-node [<node-id>]'
622 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800623 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800624 """
andrewonlab86dc3082014-10-13 18:18:38 -0400625 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400626
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700628 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700629 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800630 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700631 if re.search( "Error", handle ):
632 main.log.error( "Error in removing node" )
633 main.log.error( handle )
634 return main.FALSE
635 else:
636 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800637 except AssertionError:
638 main.log.exception( "" )
639 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800640 except TypeError:
641 main.log.exception( self.name + ": Object not as expected" )
642 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400643 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800644 main.log.error( self.name + ": EOF exception found" )
645 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700646 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800647 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800648 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700649 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400650
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700651 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800652 """
andrewonlab7c211572014-10-15 16:45:20 -0400653 List the nodes currently visible
654 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700655 Optional argument:
656 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800657 """
andrewonlab7c211572014-10-15 16:45:20 -0400658 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700659 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700660 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700661 cmdStr += " -j"
662 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700663 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800664 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700665 return output
Jon Hallc6793552016-01-19 14:18:37 -0800666 except AssertionError:
667 main.log.exception( "" )
668 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800669 except TypeError:
670 main.log.exception( self.name + ": Object not as expected" )
671 return None
andrewonlab7c211572014-10-15 16:45:20 -0400672 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800673 main.log.error( self.name + ": EOF exception found" )
674 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700675 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800676 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800677 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700678 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400679
kelvin8ec71442015-01-15 16:57:00 -0800680 def topology( self ):
681 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700682 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700683 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700684 Return:
685 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800686 """
andrewonlab95ce8322014-10-13 14:12:04 -0400687 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700688 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800690 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800691 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700692 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400693 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800694 except AssertionError:
695 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800696 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800697 except TypeError:
698 main.log.exception( self.name + ": Object not as expected" )
699 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400700 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800701 main.log.error( self.name + ": EOF exception found" )
702 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700703 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800704 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800705 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700706 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800707
jenkins7ead5a82015-03-13 10:28:21 -0700708 def deviceRemove( self, deviceId ):
709 """
710 Removes particular device from storage
711
712 TODO: refactor this function
713 """
714 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700715 cmdStr = "device-remove " + str( deviceId )
716 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800717 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800718 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700719 if re.search( "Error", handle ):
720 main.log.error( "Error in removing device" )
721 main.log.error( handle )
722 return main.FALSE
723 else:
724 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800725 except AssertionError:
726 main.log.exception( "" )
727 return None
jenkins7ead5a82015-03-13 10:28:21 -0700728 except TypeError:
729 main.log.exception( self.name + ": Object not as expected" )
730 return None
731 except pexpect.EOF:
732 main.log.error( self.name + ": EOF exception found" )
733 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700734 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700735 except Exception:
736 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700737 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700738
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800740 """
Jon Hall7b02d952014-10-17 20:14:54 -0400741 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400742 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800743 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800744 """
andrewonlab86dc3082014-10-13 18:18:38 -0400745 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700746 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700748 cmdStr += " -j"
749 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800750 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800751 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700752 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800753 except AssertionError:
754 main.log.exception( "" )
755 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800756 except TypeError:
757 main.log.exception( self.name + ": Object not as expected" )
758 return None
andrewonlab7c211572014-10-15 16:45:20 -0400759 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800760 main.log.error( self.name + ": EOF exception found" )
761 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700762 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800763 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800764 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700765 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400766
kelvin-onlabd3b64892015-01-20 13:26:24 -0800767 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800768 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800769 This balances the devices across all controllers
770 by issuing command: 'onos> onos:balance-masters'
771 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800772 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800773 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800774 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700775 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800776 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800777 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700778 if re.search( "Error", handle ):
779 main.log.error( "Error in balancing masters" )
780 main.log.error( handle )
781 return main.FALSE
782 else:
783 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800784 except AssertionError:
785 main.log.exception( "" )
786 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800787 except TypeError:
788 main.log.exception( self.name + ": Object not as expected" )
789 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800790 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800791 main.log.error( self.name + ": EOF exception found" )
792 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700793 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800794 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800795 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700796 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800797
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000798 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700799 """
800 Returns the output of the masters command.
801 Optional argument:
802 * jsonFormat - boolean indicating if you want output in json
803 """
804 try:
805 cmdStr = "onos:masters"
806 if jsonFormat:
807 cmdStr += " -j"
808 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700809 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800810 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700811 return output
Jon Hallc6793552016-01-19 14:18:37 -0800812 except AssertionError:
813 main.log.exception( "" )
814 return None
acsmars24950022015-07-30 18:00:43 -0700815 except TypeError:
816 main.log.exception( self.name + ": Object not as expected" )
817 return None
818 except pexpect.EOF:
819 main.log.error( self.name + ": EOF exception found" )
820 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700821 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700822 except Exception:
823 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700824 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700825
Jon Hallc6793552016-01-19 14:18:37 -0800826 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700827 """
828 Uses the master command to check that the devices' leadership
829 is evenly divided
830
831 Dependencies: checkMasters() and summary()
832
Jon Hall6509dbf2016-06-21 17:01:17 -0700833 Returns main.TRUE if the devices are balanced
834 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700835 Exits on Exception
836 Returns None on TypeError
837 """
838 try:
Jon Hallc6793552016-01-19 14:18:37 -0800839 summaryOutput = self.summary()
840 totalDevices = json.loads( summaryOutput )[ "devices" ]
841 except ( TypeError, ValueError ):
842 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
843 return None
844 try:
acsmars24950022015-07-30 18:00:43 -0700845 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800846 mastersOutput = self.checkMasters()
847 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700848 first = masters[ 0 ][ "size" ]
849 for master in masters:
850 totalOwnedDevices += master[ "size" ]
851 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
852 main.log.error( "Mastership not balanced" )
853 main.log.info( "\n" + self.checkMasters( False ) )
854 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700855 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700856 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700857 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800858 except ( TypeError, ValueError ):
859 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700860 return None
861 except pexpect.EOF:
862 main.log.error( self.name + ": EOF exception found" )
863 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700864 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700865 except Exception:
866 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700867 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700868
YPZhangfebf7302016-05-24 16:45:56 -0700869 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800870 """
Jon Halle8217482014-10-17 13:49:14 -0400871 Lists all core links
872 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800873 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800874 """
Jon Halle8217482014-10-17 13:49:14 -0400875 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700876 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800877 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700878 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700879 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800880 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800881 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700882 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800883 except AssertionError:
884 main.log.exception( "" )
885 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800886 except TypeError:
887 main.log.exception( self.name + ": Object not as expected" )
888 return None
Jon Halle8217482014-10-17 13:49:14 -0400889 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800890 main.log.error( self.name + ": EOF exception found" )
891 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700892 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800893 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800894 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700895 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400896
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800898 """
Jon Halle8217482014-10-17 13:49:14 -0400899 Lists all ports
900 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800901 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800902 """
Jon Halle8217482014-10-17 13:49:14 -0400903 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700904 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800905 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700906 cmdStr += " -j"
907 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800908 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800909 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700910 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800911 except AssertionError:
912 main.log.exception( "" )
913 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800914 except TypeError:
915 main.log.exception( self.name + ": Object not as expected" )
916 return None
Jon Halle8217482014-10-17 13:49:14 -0400917 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800918 main.log.error( self.name + ": EOF exception found" )
919 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700920 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800921 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800922 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700923 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400924
kelvin-onlabd3b64892015-01-20 13:26:24 -0800925 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800926 """
Jon Hall983a1702014-10-28 18:44:22 -0400927 Lists all devices and the controllers with roles assigned to them
928 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800929 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800930 """
andrewonlab7c211572014-10-15 16:45:20 -0400931 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700932 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800933 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700934 cmdStr += " -j"
935 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800936 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800937 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700938 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800939 except AssertionError:
940 main.log.exception( "" )
941 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800942 except TypeError:
943 main.log.exception( self.name + ": Object not as expected" )
944 return None
Jon Hall983a1702014-10-28 18:44:22 -0400945 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800946 main.log.error( self.name + ": EOF exception found" )
947 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700948 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800949 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800950 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700951 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -0400952
kelvin-onlabd3b64892015-01-20 13:26:24 -0800953 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800954 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800955 Given the a string containing the json representation of the "roles"
956 cli command and a partial or whole device id, returns a json object
957 containing the roles output for the first device whose id contains
958 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400959
960 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800961 A dict of the role assignments for the given device or
962 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800963 """
Jon Hall983a1702014-10-28 18:44:22 -0400964 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400966 return None
967 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800968 rawRoles = self.roles()
969 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800970 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800972 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800973 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400974 return device
975 return None
Jon Hallc6793552016-01-19 14:18:37 -0800976 except ( TypeError, ValueError ):
977 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800978 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400979 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800980 main.log.error( self.name + ": EOF exception found" )
981 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700982 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800983 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800984 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700985 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -0800986
kelvin-onlabd3b64892015-01-20 13:26:24 -0800987 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800988 """
Jon Hall94fd0472014-12-08 11:52:42 -0800989 Iterates through each device and checks if there is a master assigned
990 Returns: main.TRUE if each device has a master
991 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800992 """
Jon Hall94fd0472014-12-08 11:52:42 -0800993 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 rawRoles = self.roles()
995 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800996 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800997 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800998 # print device
999 if device[ 'master' ] == "none":
1000 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001001 return main.FALSE
1002 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001003 except ( TypeError, ValueError ):
1004 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001005 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001006 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001007 main.log.error( self.name + ": EOF exception found" )
1008 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001009 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001010 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001011 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001012 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001013
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001015 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001016 Returns string of paths, and the cost.
1017 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001018 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001019 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001020 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1021 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001022 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001023 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001024 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001025 main.log.error( "Error in getting paths" )
1026 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001027 else:
kelvin8ec71442015-01-15 16:57:00 -08001028 path = handle.split( ";" )[ 0 ]
1029 cost = handle.split( ";" )[ 1 ]
1030 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001031 except AssertionError:
1032 main.log.exception( "" )
1033 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001034 except TypeError:
1035 main.log.exception( self.name + ": Object not as expected" )
1036 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001037 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001038 main.log.error( self.name + ": EOF exception found" )
1039 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001040 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001041 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001042 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001043 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001044
kelvin-onlabd3b64892015-01-20 13:26:24 -08001045 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001046 """
Jon Hallffb386d2014-11-21 13:43:38 -08001047 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001048 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001049 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001050 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001051 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001052 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001054 cmdStr += " -j"
1055 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001056 if handle:
1057 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001058 # TODO: Maybe make this less hardcoded
1059 # ConsistentMap Exceptions
1060 assert "org.onosproject.store.service" not in handle
1061 # Node not leader
1062 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001063 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001064 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001065 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001066 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001067 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001068 except TypeError:
1069 main.log.exception( self.name + ": Object not as expected" )
1070 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001071 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001072 main.log.error( self.name + ": EOF exception found" )
1073 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001074 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001075 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001076 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001077 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001078
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001080 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001081 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001082
Jon Hallefbd9792015-03-05 16:11:36 -08001083 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001084 partial mac address
1085
Jon Hall42db6dc2014-10-24 19:03:48 -04001086 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001087 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001088 try:
kelvin8ec71442015-01-15 16:57:00 -08001089 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001090 return None
1091 else:
1092 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 rawHosts = self.hosts()
1094 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001095 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001097 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001098 if not host:
1099 pass
1100 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001101 return host
1102 return None
Jon Hallc6793552016-01-19 14:18:37 -08001103 except ( TypeError, ValueError ):
1104 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001105 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001106 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001107 main.log.error( self.name + ": EOF exception found" )
1108 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001109 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001110 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001111 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001112 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001113
kelvin-onlabd3b64892015-01-20 13:26:24 -08001114 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001115 """
1116 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001117 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001118
andrewonlab3f0a4af2014-10-17 12:25:14 -04001119 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001121 IMPORTANT:
1122 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001123 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001124 Furthermore, it assumes that value of VLAN is '-1'
1125 Description:
kelvin8ec71442015-01-15 16:57:00 -08001126 Converts mininet hosts ( h1, h2, h3... ) into
1127 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1128 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001129 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001130 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001131
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001133 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 hostHex = hex( int( host ) ).zfill( 12 )
1135 hostHex = str( hostHex ).replace( 'x', '0' )
1136 i = iter( str( hostHex ) )
1137 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1138 hostHex = hostHex + "/-1"
1139 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001140
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001142
Jon Halld4d4b372015-01-28 16:02:41 -08001143 except TypeError:
1144 main.log.exception( self.name + ": Object not as expected" )
1145 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001146 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001147 main.log.error( self.name + ": EOF exception found" )
1148 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001149 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001150 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001151 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001152 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001153
You Wangbc898b82018-05-03 16:22:34 -07001154 def verifyHostLocation( self, hostIp, location ):
1155 """
1156 Description:
1157 Verify the host given is discovered in all locations expected
1158 Required:
1159 hostIp: IP address of the host
1160 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1161 Could be a string or list
1162 Returns:
1163 main.TRUE if host is discovered on all locations provided
1164 main.FALSE otherwise
1165 """
1166 import json
1167 locations = [ location ] if isinstance( location, str ) else location
1168 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1169 try:
1170 hosts = self.hosts()
1171 hosts = json.loads( hosts )
1172 targetHost = None
1173 for host in hosts:
1174 if hostIp in host[ "ipAddresses" ]:
1175 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001176 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001177 result = main.TRUE
1178 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1179 for loc in locations:
1180 discovered = False
1181 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001182 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1183 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001184 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001185 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001186 break
1187 if discovered:
1188 locationsDiscovered.remove( locDiscovered )
1189 else:
1190 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1191 result = main.FALSE
1192 if locationsDiscovered:
1193 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1194 result = main.FALSE
1195 return result
1196 except KeyError:
1197 main.log.exception( self.name + ": host data not as expected: " + hosts )
1198 return None
1199 except pexpect.EOF:
1200 main.log.error( self.name + ": EOF exception found" )
1201 main.log.error( self.name + ": " + self.handle.before )
1202 main.cleanAndExit()
1203 except Exception:
1204 main.log.exception( self.name + ": Uncaught exception" )
1205 return None
1206
You Wang53dba1e2018-02-02 17:45:44 -08001207 def verifyHostIp( self, hostList=[], prefix="" ):
1208 """
1209 Description:
1210 Verify that all hosts have IP address assigned to them
1211 Optional:
1212 hostList: If specified, verifications only happen to the hosts
1213 in hostList
1214 prefix: at least one of the ip address assigned to the host
1215 needs to have the specified prefix
1216 Returns:
1217 main.TRUE if all hosts have specific IP address assigned;
1218 main.FALSE otherwise
1219 """
1220 import json
1221 try:
1222 hosts = self.hosts()
1223 hosts = json.loads( hosts )
1224 if not hostList:
1225 hostList = [ host[ "id" ] for host in hosts ]
1226 for host in hosts:
1227 hostId = host[ "id" ]
1228 if hostId not in hostList:
1229 continue
1230 ipList = host[ "ipAddresses" ]
1231 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1232 if not ipList:
1233 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1234 else:
1235 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1236 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1237 else:
1238 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1239 hostList.remove( hostId )
1240 if hostList:
1241 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1242 return main.FALSE
1243 else:
1244 return main.TRUE
1245 except KeyError:
1246 main.log.exception( self.name + ": host data not as expected: " + hosts )
1247 return None
1248 except pexpect.EOF:
1249 main.log.error( self.name + ": EOF exception found" )
1250 main.log.error( self.name + ": " + self.handle.before )
1251 main.cleanAndExit()
1252 except Exception:
1253 main.log.exception( self.name + ": Uncaught exception" )
1254 return None
1255
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001256 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001257 """
andrewonlabe6745342014-10-17 14:29:13 -04001258 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 * hostIdOne: ONOS host id for host1
1260 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001261 Optional:
1262 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001263 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001264 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001265 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001266 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001267 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001268 Returns:
1269 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001270 """
andrewonlabe6745342014-10-17 14:29:13 -04001271 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001272 cmdStr = "add-host-intent "
1273 if vlanId:
1274 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001275 if setVlan:
1276 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001277 if encap:
1278 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001279 if bandwidth:
1280 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001281 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001282 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001283 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001284 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001285 if re.search( "Error", handle ):
1286 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001287 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001288 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001289 else:
1290 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001291 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001292 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001293 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001294 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001295 else:
1296 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001297 main.log.debug( "Response from ONOS was: " +
1298 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001299 return None
Jon Hallc6793552016-01-19 14:18:37 -08001300 except AssertionError:
1301 main.log.exception( "" )
1302 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001303 except TypeError:
1304 main.log.exception( self.name + ": Object not as expected" )
1305 return None
andrewonlabe6745342014-10-17 14:29:13 -04001306 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001307 main.log.error( self.name + ": EOF exception found" )
1308 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001309 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001310 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001311 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001312 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001313
kelvin-onlabd3b64892015-01-20 13:26:24 -08001314 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001315 """
andrewonlab7b31d232014-10-24 13:31:47 -04001316 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001317 * ingressDevice: device id of ingress device
1318 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001319 Optional:
1320 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001321 Description:
1322 Adds an optical intent by specifying an ingress and egress device
1323 Returns:
1324 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001325 """
andrewonlab7b31d232014-10-24 13:31:47 -04001326 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001327 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1328 " " + str( egressDevice )
1329 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001330 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001331 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001332 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001333 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001334 main.log.error( "Error in adding Optical intent" )
1335 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001336 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001337 main.log.info( "Optical intent installed between " +
1338 str( ingressDevice ) + " and " +
1339 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001340 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001341 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001342 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001343 else:
1344 main.log.error( "Error, intent ID not found" )
1345 return None
Jon Hallc6793552016-01-19 14:18:37 -08001346 except AssertionError:
1347 main.log.exception( "" )
1348 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001349 except TypeError:
1350 main.log.exception( self.name + ": Object not as expected" )
1351 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001352 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001353 main.log.error( self.name + ": EOF exception found" )
1354 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001355 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001356 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001357 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001358 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001359
kelvin-onlabd3b64892015-01-20 13:26:24 -08001360 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001361 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001362 ingressDevice,
1363 egressDevice,
1364 portIngress="",
1365 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001366 ethType="",
1367 ethSrc="",
1368 ethDst="",
1369 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001370 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001371 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001372 ipProto="",
1373 ipSrc="",
1374 ipDst="",
1375 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001376 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001377 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001378 setVlan="",
1379 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001380 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001381 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001382 * ingressDevice: device id of ingress device
1383 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001384 Optional:
1385 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001386 * ethSrc: specify ethSrc ( i.e. src mac addr )
1387 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001388 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001389 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001390 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001391 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001392 * ipSrc: specify ip source address
1393 * ipDst: specify ip destination address
1394 * tcpSrc: specify tcp source port
1395 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001396 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001397 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001398 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001399 Description:
kelvin8ec71442015-01-15 16:57:00 -08001400 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001401 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001402 Returns:
1403 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001404
Jon Halle3f39ff2015-01-13 11:50:53 -08001405 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001406 options developers provide for point-to-point
1407 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001408 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001409 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001410 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001411
Jeremy Songsterff553672016-05-12 17:06:23 -07001412 if ethType:
1413 cmd += " --ethType " + str( ethType )
1414 if ethSrc:
1415 cmd += " --ethSrc " + str( ethSrc )
1416 if ethDst:
1417 cmd += " --ethDst " + str( ethDst )
1418 if bandwidth:
1419 cmd += " --bandwidth " + str( bandwidth )
1420 if lambdaAlloc:
1421 cmd += " --lambda "
1422 if ipProto:
1423 cmd += " --ipProto " + str( ipProto )
1424 if ipSrc:
1425 cmd += " --ipSrc " + str( ipSrc )
1426 if ipDst:
1427 cmd += " --ipDst " + str( ipDst )
1428 if tcpSrc:
1429 cmd += " --tcpSrc " + str( tcpSrc )
1430 if tcpDst:
1431 cmd += " --tcpDst " + str( tcpDst )
1432 if vlanId:
1433 cmd += " -v " + str( vlanId )
1434 if setVlan:
1435 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001436 if encap:
1437 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001438 if protected:
1439 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001440
kelvin8ec71442015-01-15 16:57:00 -08001441 # Check whether the user appended the port
1442 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001443 if "/" in ingressDevice:
1444 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001445 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001446 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001447 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001448 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001449 # Would it make sense to throw an exception and exit
1450 # the test?
1451 return None
andrewonlab36af3822014-11-18 17:48:18 -05001452
kelvin8ec71442015-01-15 16:57:00 -08001453 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001454 str( ingressDevice ) + "/" +\
1455 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001456
kelvin-onlabd3b64892015-01-20 13:26:24 -08001457 if "/" in egressDevice:
1458 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001459 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001460 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001461 main.log.error( "You must specify the egress port" )
1462 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001463
kelvin8ec71442015-01-15 16:57:00 -08001464 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001465 str( egressDevice ) + "/" +\
1466 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001467
kelvin-onlab898a6c62015-01-16 14:13:53 -08001468 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001469 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001470 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001471 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001472 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001473 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001474 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001475 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001476 # TODO: print out all the options in this message?
1477 main.log.info( "Point-to-point intent installed between " +
1478 str( ingressDevice ) + " and " +
1479 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001480 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001481 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001482 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001483 else:
1484 main.log.error( "Error, intent ID not found" )
1485 return None
Jon Hallc6793552016-01-19 14:18:37 -08001486 except AssertionError:
1487 main.log.exception( "" )
1488 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001489 except TypeError:
1490 main.log.exception( self.name + ": Object not as expected" )
1491 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001492 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001493 main.log.error( self.name + ": EOF exception found" )
1494 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001495 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001496 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001497 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001498 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001499
kelvin-onlabd3b64892015-01-20 13:26:24 -08001500 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001501 self,
shahshreyac2f97072015-03-19 17:04:29 -07001502 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001503 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001504 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001505 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001506 ethType="",
1507 ethSrc="",
1508 ethDst="",
1509 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001510 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001511 ipProto="",
1512 ipSrc="",
1513 ipDst="",
1514 tcpSrc="",
1515 tcpDst="",
1516 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001517 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001518 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001519 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001520 partial=False,
1521 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001522 """
shahshreyad0c80432014-12-04 16:56:05 -08001523 Note:
shahshreya70622b12015-03-19 17:19:00 -07001524 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001525 is same. That is, all ingress devices include port numbers
1526 with a "/" or all ingress devices could specify device
1527 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001528 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001529 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001530 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001531 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001532 Optional:
1533 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001534 * ethSrc: specify ethSrc ( i.e. src mac addr )
1535 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001536 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001537 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001538 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001539 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001540 * ipSrc: specify ip source address
1541 * ipDst: specify ip destination address
1542 * tcpSrc: specify tcp source port
1543 * tcpDst: specify tcp destination port
1544 * setEthSrc: action to Rewrite Source MAC Address
1545 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001546 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001547 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001548 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001549 Description:
kelvin8ec71442015-01-15 16:57:00 -08001550 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001551 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001552 Returns:
1553 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001554
Jon Halle3f39ff2015-01-13 11:50:53 -08001555 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001556 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001557 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001558 """
shahshreyad0c80432014-12-04 16:56:05 -08001559 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001560 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001561
Jeremy Songsterff553672016-05-12 17:06:23 -07001562 if ethType:
1563 cmd += " --ethType " + str( ethType )
1564 if ethSrc:
1565 cmd += " --ethSrc " + str( ethSrc )
1566 if ethDst:
1567 cmd += " --ethDst " + str( ethDst )
1568 if bandwidth:
1569 cmd += " --bandwidth " + str( bandwidth )
1570 if lambdaAlloc:
1571 cmd += " --lambda "
1572 if ipProto:
1573 cmd += " --ipProto " + str( ipProto )
1574 if ipSrc:
1575 cmd += " --ipSrc " + str( ipSrc )
1576 if ipDst:
1577 cmd += " --ipDst " + str( ipDst )
1578 if tcpSrc:
1579 cmd += " --tcpSrc " + str( tcpSrc )
1580 if tcpDst:
1581 cmd += " --tcpDst " + str( tcpDst )
1582 if setEthSrc:
1583 cmd += " --setEthSrc " + str( setEthSrc )
1584 if setEthDst:
1585 cmd += " --setEthDst " + str( setEthDst )
1586 if vlanId:
1587 cmd += " -v " + str( vlanId )
1588 if setVlan:
1589 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001590 if partial:
1591 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001592 if encap:
1593 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001594
kelvin8ec71442015-01-15 16:57:00 -08001595 # Check whether the user appended the port
1596 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001597
1598 if portIngressList is None:
1599 for ingressDevice in ingressDeviceList:
1600 if "/" in ingressDevice:
1601 cmd += " " + str( ingressDevice )
1602 else:
1603 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001604 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001605 # TODO: perhaps more meaningful return
1606 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001607 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001608 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001609 for ingressDevice, portIngress in zip( ingressDeviceList,
1610 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001611 cmd += " " + \
1612 str( ingressDevice ) + "/" +\
1613 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001614 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001615 main.log.error( "Device list and port list does not " +
1616 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001617 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001618 if "/" in egressDevice:
1619 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001620 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001621 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001622 main.log.error( "You must specify " +
1623 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001624 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001625
kelvin8ec71442015-01-15 16:57:00 -08001626 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001627 str( egressDevice ) + "/" +\
1628 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001629 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001630 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001631 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001632 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001633 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001634 main.log.error( "Error in adding multipoint-to-singlepoint " +
1635 "intent" )
1636 return None
shahshreyad0c80432014-12-04 16:56:05 -08001637 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001638 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001639 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001640 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001641 else:
1642 main.log.error( "Error, intent ID not found" )
1643 return None
Jon Hallc6793552016-01-19 14:18:37 -08001644 except AssertionError:
1645 main.log.exception( "" )
1646 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001647 except TypeError:
1648 main.log.exception( self.name + ": Object not as expected" )
1649 return None
1650 except pexpect.EOF:
1651 main.log.error( self.name + ": EOF exception found" )
1652 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001653 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001654 except Exception:
1655 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001656 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001657
1658 def addSinglepointToMultipointIntent(
1659 self,
1660 ingressDevice,
1661 egressDeviceList,
1662 portIngress="",
1663 portEgressList=None,
1664 ethType="",
1665 ethSrc="",
1666 ethDst="",
1667 bandwidth="",
1668 lambdaAlloc=False,
1669 ipProto="",
1670 ipSrc="",
1671 ipDst="",
1672 tcpSrc="",
1673 tcpDst="",
1674 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001675 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001676 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001677 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001678 partial=False,
1679 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001680 """
1681 Note:
1682 This function assumes the format of all egress devices
1683 is same. That is, all egress devices include port numbers
1684 with a "/" or all egress devices could specify device
1685 ids and port numbers seperately.
1686 Required:
1687 * EgressDeviceList: List of device ids of egress device
1688 ( Atleast 2 eress devices required in the list )
1689 * ingressDevice: device id of ingress device
1690 Optional:
1691 * ethType: specify ethType
1692 * ethSrc: specify ethSrc ( i.e. src mac addr )
1693 * ethDst: specify ethDst ( i.e. dst mac addr )
1694 * bandwidth: specify bandwidth capacity of link
1695 * lambdaAlloc: if True, intent will allocate lambda
1696 for the specified intent
1697 * ipProto: specify ip protocol
1698 * ipSrc: specify ip source address
1699 * ipDst: specify ip destination address
1700 * tcpSrc: specify tcp source port
1701 * tcpDst: specify tcp destination port
1702 * setEthSrc: action to Rewrite Source MAC Address
1703 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001704 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001705 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001706 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001707 Description:
1708 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1709 specifying device id's and optional fields
1710 Returns:
1711 A string of the intent id or None on error
1712
1713 NOTE: This function may change depending on the
1714 options developers provide for singlepoint-to-multipoint
1715 intent via cli
1716 """
1717 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001718 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001719
Jeremy Songsterff553672016-05-12 17:06:23 -07001720 if ethType:
1721 cmd += " --ethType " + str( ethType )
1722 if ethSrc:
1723 cmd += " --ethSrc " + str( ethSrc )
1724 if ethDst:
1725 cmd += " --ethDst " + str( ethDst )
1726 if bandwidth:
1727 cmd += " --bandwidth " + str( bandwidth )
1728 if lambdaAlloc:
1729 cmd += " --lambda "
1730 if ipProto:
1731 cmd += " --ipProto " + str( ipProto )
1732 if ipSrc:
1733 cmd += " --ipSrc " + str( ipSrc )
1734 if ipDst:
1735 cmd += " --ipDst " + str( ipDst )
1736 if tcpSrc:
1737 cmd += " --tcpSrc " + str( tcpSrc )
1738 if tcpDst:
1739 cmd += " --tcpDst " + str( tcpDst )
1740 if setEthSrc:
1741 cmd += " --setEthSrc " + str( setEthSrc )
1742 if setEthDst:
1743 cmd += " --setEthDst " + str( setEthDst )
1744 if vlanId:
1745 cmd += " -v " + str( vlanId )
1746 if setVlan:
1747 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001748 if partial:
1749 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001750 if encap:
1751 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001752
1753 # Check whether the user appended the port
1754 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001755
kelvin-onlabb9408212015-04-01 13:34:04 -07001756 if "/" in ingressDevice:
1757 cmd += " " + str( ingressDevice )
1758 else:
1759 if not portIngress:
1760 main.log.error( "You must specify " +
1761 "the Ingress port" )
1762 return main.FALSE
1763
1764 cmd += " " +\
1765 str( ingressDevice ) + "/" +\
1766 str( portIngress )
1767
1768 if portEgressList is None:
1769 for egressDevice in egressDeviceList:
1770 if "/" in egressDevice:
1771 cmd += " " + str( egressDevice )
1772 else:
1773 main.log.error( "You must specify " +
1774 "the egress port" )
1775 # TODO: perhaps more meaningful return
1776 return main.FALSE
1777 else:
1778 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001779 for egressDevice, portEgress in zip( egressDeviceList,
1780 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001781 cmd += " " + \
1782 str( egressDevice ) + "/" +\
1783 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001784 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001785 main.log.error( "Device list and port list does not " +
1786 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001787 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001788 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001789 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001790 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001791 # If error, return error message
1792 if re.search( "Error", handle ):
1793 main.log.error( "Error in adding singlepoint-to-multipoint " +
1794 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001795 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001796 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001797 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001798 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001799 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001800 else:
1801 main.log.error( "Error, intent ID not found" )
1802 return None
Jon Hallc6793552016-01-19 14:18:37 -08001803 except AssertionError:
1804 main.log.exception( "" )
1805 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001806 except TypeError:
1807 main.log.exception( self.name + ": Object not as expected" )
1808 return None
shahshreyad0c80432014-12-04 16:56:05 -08001809 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001810 main.log.error( self.name + ": EOF exception found" )
1811 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001812 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001813 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001814 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001815 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001816
Hari Krishna9e232602015-04-13 17:29:08 -07001817 def addMplsIntent(
1818 self,
1819 ingressDevice,
1820 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001821 ingressPort="",
1822 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001823 ethType="",
1824 ethSrc="",
1825 ethDst="",
1826 bandwidth="",
1827 lambdaAlloc=False,
1828 ipProto="",
1829 ipSrc="",
1830 ipDst="",
1831 tcpSrc="",
1832 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001833 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001834 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001835 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001836 """
1837 Required:
1838 * ingressDevice: device id of ingress device
1839 * egressDevice: device id of egress device
1840 Optional:
1841 * ethType: specify ethType
1842 * ethSrc: specify ethSrc ( i.e. src mac addr )
1843 * ethDst: specify ethDst ( i.e. dst mac addr )
1844 * bandwidth: specify bandwidth capacity of link
1845 * lambdaAlloc: if True, intent will allocate lambda
1846 for the specified intent
1847 * ipProto: specify ip protocol
1848 * ipSrc: specify ip source address
1849 * ipDst: specify ip destination address
1850 * tcpSrc: specify tcp source port
1851 * tcpDst: specify tcp destination port
1852 * ingressLabel: Ingress MPLS label
1853 * egressLabel: Egress MPLS label
1854 Description:
1855 Adds MPLS intent by
1856 specifying device id's and optional fields
1857 Returns:
1858 A string of the intent id or None on error
1859
1860 NOTE: This function may change depending on the
1861 options developers provide for MPLS
1862 intent via cli
1863 """
1864 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001865 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001866
Jeremy Songsterff553672016-05-12 17:06:23 -07001867 if ethType:
1868 cmd += " --ethType " + str( ethType )
1869 if ethSrc:
1870 cmd += " --ethSrc " + str( ethSrc )
1871 if ethDst:
1872 cmd += " --ethDst " + str( ethDst )
1873 if bandwidth:
1874 cmd += " --bandwidth " + str( bandwidth )
1875 if lambdaAlloc:
1876 cmd += " --lambda "
1877 if ipProto:
1878 cmd += " --ipProto " + str( ipProto )
1879 if ipSrc:
1880 cmd += " --ipSrc " + str( ipSrc )
1881 if ipDst:
1882 cmd += " --ipDst " + str( ipDst )
1883 if tcpSrc:
1884 cmd += " --tcpSrc " + str( tcpSrc )
1885 if tcpDst:
1886 cmd += " --tcpDst " + str( tcpDst )
1887 if ingressLabel:
1888 cmd += " --ingressLabel " + str( ingressLabel )
1889 if egressLabel:
1890 cmd += " --egressLabel " + str( egressLabel )
1891 if priority:
1892 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001893
1894 # Check whether the user appended the port
1895 # or provided it as an input
1896 if "/" in ingressDevice:
1897 cmd += " " + str( ingressDevice )
1898 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001899 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001900 main.log.error( "You must specify the ingress port" )
1901 return None
1902
1903 cmd += " " + \
1904 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001905 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001906
1907 if "/" in egressDevice:
1908 cmd += " " + str( egressDevice )
1909 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001910 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001911 main.log.error( "You must specify the egress port" )
1912 return None
1913
1914 cmd += " " +\
1915 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001916 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001917
1918 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001919 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001920 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001921 # If error, return error message
1922 if re.search( "Error", handle ):
1923 main.log.error( "Error in adding mpls intent" )
1924 return None
1925 else:
1926 # TODO: print out all the options in this message?
1927 main.log.info( "MPLS intent installed between " +
1928 str( ingressDevice ) + " and " +
1929 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001930 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07001931 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001932 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07001933 else:
1934 main.log.error( "Error, intent ID not found" )
1935 return None
Jon Hallc6793552016-01-19 14:18:37 -08001936 except AssertionError:
1937 main.log.exception( "" )
1938 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001939 except TypeError:
1940 main.log.exception( self.name + ": Object not as expected" )
1941 return None
1942 except pexpect.EOF:
1943 main.log.error( self.name + ": EOF exception found" )
1944 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001945 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001946 except Exception:
1947 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001948 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001949
Jon Hallefbd9792015-03-05 16:11:36 -08001950 def removeIntent( self, intentId, app='org.onosproject.cli',
1951 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001952 """
shahshreya1c818fc2015-02-26 13:44:08 -08001953 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001954 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001955 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001956 -p or --purge: Purge the intent from the store after removal
1957
Jon Halle3f39ff2015-01-13 11:50:53 -08001958 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001959 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001960 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001961 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001962 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001963 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001964 if purge:
1965 cmdStr += " -p"
1966 if sync:
1967 cmdStr += " -s"
1968
1969 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001970 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001971 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001972 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001973 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001974 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001975 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001976 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001977 # TODO: Should this be main.TRUE
1978 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001979 except AssertionError:
1980 main.log.exception( "" )
1981 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001982 except TypeError:
1983 main.log.exception( self.name + ": Object not as expected" )
1984 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001985 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001986 main.log.error( self.name + ": EOF exception found" )
1987 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001988 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001989 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001990 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001991 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04001992
YPZhangfebf7302016-05-24 16:45:56 -07001993 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001994 """
1995 Description:
1996 Remove all the intents
1997 Optional args:-
1998 -s or --sync: Waits for the removal before returning
1999 -p or --purge: Purge the intent from the store after removal
2000 Returns:
2001 Returns main.TRUE if all intents are removed, otherwise returns
2002 main.FALSE; Returns None for exception
2003 """
2004 try:
2005 cmdStr = "remove-intent"
2006 if purge:
2007 cmdStr += " -p"
2008 if sync:
2009 cmdStr += " -s"
2010
2011 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002012 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002013 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002014 assert "Command not found:" not in handle, handle
2015 if re.search( "Error", handle ):
2016 main.log.error( "Error in removing intent" )
2017 return main.FALSE
2018 else:
2019 return main.TRUE
2020 except AssertionError:
2021 main.log.exception( "" )
2022 return None
2023 except TypeError:
2024 main.log.exception( self.name + ": Object not as expected" )
2025 return None
2026 except pexpect.EOF:
2027 main.log.error( self.name + ": EOF exception found" )
2028 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002029 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002030 except Exception:
2031 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002032 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002033
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002034 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002035 """
2036 Purges all WITHDRAWN Intents
2037 """
2038 try:
2039 cmdStr = "purge-intents"
2040 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002041 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002042 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002043 if re.search( "Error", handle ):
2044 main.log.error( "Error in purging intents" )
2045 return main.FALSE
2046 else:
2047 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002048 except AssertionError:
2049 main.log.exception( "" )
2050 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002051 except TypeError:
2052 main.log.exception( self.name + ": Object not as expected" )
2053 return None
2054 except pexpect.EOF:
2055 main.log.error( self.name + ": EOF exception found" )
2056 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002057 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002058 except Exception:
2059 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002060 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002061
Devin Lime6fe3c42017-10-18 16:28:40 -07002062 def wipeout( self ):
2063 """
2064 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2065 """
2066 try:
2067 cmdStr = "wipe-out please"
2068 handle = self.sendline( cmdStr, timeout=60 )
2069 assert handle is not None, "Error in sendline"
2070 assert "Command not found:" not in handle, handle
2071 return main.TRUE
2072 except AssertionError:
2073 main.log.exception( "" )
2074 return None
2075 except TypeError:
2076 main.log.exception( self.name + ": Object not as expected" )
2077 return None
2078 except pexpect.EOF:
2079 main.log.error( self.name + ": EOF exception found" )
2080 main.log.error( self.name + ": " + self.handle.before )
2081 main.cleanAndExit()
2082 except Exception:
2083 main.log.exception( self.name + ": Uncaught exception!" )
2084 main.cleanAndExit()
2085
kelvin-onlabd3b64892015-01-20 13:26:24 -08002086 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002087 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002088 NOTE: This method should be used after installing application:
2089 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002090 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002091 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002092 Description:
2093 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002094 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002095 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002096 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002097 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002098 cmdStr += " -j"
2099 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002100 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002101 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002102 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002103 except AssertionError:
2104 main.log.exception( "" )
2105 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002106 except TypeError:
2107 main.log.exception( self.name + ": Object not as expected" )
2108 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002109 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002110 main.log.error( self.name + ": EOF exception found" )
2111 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002112 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002113 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002114 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002115 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002116
pingping-lin54b03372015-08-13 14:43:10 -07002117 def ipv4RouteNumber( self ):
2118 """
2119 NOTE: This method should be used after installing application:
2120 onos-app-sdnip
2121 Description:
2122 Obtain the total IPv4 routes number in the system
2123 """
2124 try:
Pratik Parab57963572017-05-09 11:37:54 -07002125 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002126 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002127 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002128 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002129 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002130 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002131 except AssertionError:
2132 main.log.exception( "" )
2133 return None
2134 except ( TypeError, ValueError ):
2135 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002136 return None
2137 except pexpect.EOF:
2138 main.log.error( self.name + ": EOF exception found" )
2139 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002140 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002141 except Exception:
2142 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002143 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002144
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002145 # =============Function to check Bandwidth allocation========
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002146 def allocations( self, jsonFormat = True, dollarSign = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002147 """
2148 Description:
2149 Obtain Bandwidth Allocation Information from ONOS cli.
2150 """
2151 try:
2152 cmdStr = "allocations"
2153 if jsonFormat:
2154 cmdStr += " -j"
2155 handle = self.sendline( cmdStr, timeout=300, dollarSign=True )
2156 assert handle is not None, "Error in sendline"
2157 assert "Command not found:" not in handle, handle
2158 return handle
2159 except AssertionError:
2160 main.log.exception( "" )
2161 return None
2162 except ( TypeError, ValueError ):
2163 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2164 return None
2165 except pexpect.EOF:
2166 main.log.error( self.name + ": EOF exception found" )
2167 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002168 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002169 except Exception:
2170 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002171 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002172
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002173 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002174 """
andrewonlabe6745342014-10-17 14:29:13 -04002175 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002176 Obtain intents from the ONOS cli.
2177 Optional:
2178 * jsonFormat: Enable output formatting in json, default to True
2179 * summary: Whether only output the intent summary, defaults to False
2180 * type: Only output a certain type of intent. This options is valid
2181 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002182 """
andrewonlabe6745342014-10-17 14:29:13 -04002183 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002184 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002185 if summary:
2186 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002187 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002188 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002189 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002190 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002191 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002192 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002193 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002194 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002195 else:
Jon Hallff566d52016-01-15 14:45:36 -08002196 intentType = ""
2197 # IF we want the summary of a specific intent type
2198 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002199 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002200 if intentType in jsonResult.keys():
2201 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002202 else:
Jon Hallff566d52016-01-15 14:45:36 -08002203 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002204 return handle
2205 else:
2206 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002207 except AssertionError:
2208 main.log.exception( "" )
2209 return None
2210 except ( TypeError, ValueError ):
2211 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002212 return None
2213 except pexpect.EOF:
2214 main.log.error( self.name + ": EOF exception found" )
2215 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002216 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002217 except Exception:
2218 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002219 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002220
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002221 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002222 """
You Wangfdcbfc42016-05-16 12:16:53 -07002223 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002224 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002225 list of intent IDs.
2226 Parameters:
2227 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002228 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002229 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002230 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002231 accepted.
2232 Returns a list of dictionaries if a list of intent IDs is accepted,
2233 and each dictionary maps 'id' to the Intent ID and 'state' to
2234 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002235 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002236
kelvin-onlab54400a92015-02-26 18:05:51 -08002237 try:
2238 state = "State is Undefined"
2239 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002240 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002241 else:
Jon Hallc6793552016-01-19 14:18:37 -08002242 rawJson = intentsJson
2243 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002244 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002245 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002246 if intentsId == intent[ 'id' ]:
2247 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002248 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002249 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002250 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002251 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002252 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002253 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002254 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002255 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002256 for intent in parsedIntentsJson:
2257 if intentsId[ i ] == intent[ 'id' ]:
2258 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002259 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002260 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002261 break
Jon Hallefbd9792015-03-05 16:11:36 -08002262 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002263 main.log.warn( "Could not find all intents in ONOS output" )
2264 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002265 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002266 else:
Jon Hall53158082017-05-18 11:17:00 -07002267 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002268 return None
Jon Hallc6793552016-01-19 14:18:37 -08002269 except ( TypeError, ValueError ):
2270 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002271 return None
2272 except pexpect.EOF:
2273 main.log.error( self.name + ": EOF exception found" )
2274 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002275 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002276 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002277 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002278 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002279
Jon Hallf539eb92017-05-22 17:18:42 -07002280 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002281 """
2282 Description:
2283 Check intents state
2284 Required:
2285 intentsId - List of intents ID to be checked
2286 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002287 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002288 state in the list.
2289 *NOTE: You can pass in a list of expected state,
2290 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002291 Return:
Jon Hall53158082017-05-18 11:17:00 -07002292 Returns main.TRUE only if all intent are the same as expected states,
2293 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002294 """
2295 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002296 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002297 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002298
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002299 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002300 intentsDict = []
2301 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002302 if isinstance( intentsId, types.StringType ) \
2303 and intent.get( 'id' ) == intentsId:
2304 intentsDict.append( intent )
2305 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002306 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002307 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002308
2309 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002310 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002311 "getting intents state" )
2312 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002313
2314 if isinstance( expectedState, types.StringType ):
2315 for intents in intentsDict:
2316 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002317 main.log.debug( self.name + " : Intent ID - " +
2318 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002319 " actual state = " +
2320 intents.get( 'state' )
2321 + " does not equal expected state = "
2322 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002323 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002324 elif isinstance( expectedState, types.ListType ):
2325 for intents in intentsDict:
2326 if not any( state == intents.get( 'state' ) for state in
2327 expectedState ):
2328 main.log.debug( self.name + " : Intent ID - " +
2329 intents.get( 'id' ) +
2330 " actual state = " +
2331 intents.get( 'state' ) +
2332 " does not equal expected states = "
2333 + str( expectedState ) )
2334 returnValue = main.FALSE
2335
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002336 if returnValue == main.TRUE:
2337 main.log.info( self.name + ": All " +
2338 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002339 " intents are in " + str( expectedState ) +
2340 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002341 return returnValue
2342 except TypeError:
2343 main.log.exception( self.name + ": Object not as expected" )
2344 return None
2345 except pexpect.EOF:
2346 main.log.error( self.name + ": EOF exception found" )
2347 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002348 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002349 except Exception:
2350 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002351 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002352
Jon Hallf539eb92017-05-22 17:18:42 -07002353 def compareBandwidthAllocations( self, expectedAllocations ):
2354 """
2355 Description:
2356 Compare the allocated bandwidth with the given allocations
2357 Required:
2358 expectedAllocations - The expected ONOS output of the allocations command
2359 Return:
2360 Returns main.TRUE only if all intent are the same as expected states,
2361 otherwise returns main.FALSE.
2362 """
2363 # FIXME: Convert these string comparisons to object comparisons
2364 try:
2365 returnValue = main.TRUE
2366 bandwidthFailed = False
2367 rawAlloc = self.allocations()
2368 expectedFormat = StringIO( expectedAllocations )
2369 ONOSOutput = StringIO( rawAlloc )
2370 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2371 str( expectedFormat ) ) )
2372
2373 for actual, expected in izip( ONOSOutput, expectedFormat ):
2374 actual = actual.rstrip()
2375 expected = expected.rstrip()
2376 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2377 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002378 marker1 = actual.find( 'allocated' )
2379 m1 = actual[ :marker1 ]
2380 marker2 = expected.find( 'allocated' )
2381 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002382 if m1 != m2:
2383 bandwidthFailed = True
2384 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2385 bandwidthFailed = True
2386 expectedFormat.close()
2387 ONOSOutput.close()
2388
2389 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002390 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002391 returnValue = main.FALSE
2392 return returnValue
2393 except TypeError:
2394 main.log.exception( self.name + ": Object not as expected" )
2395 return None
2396 except pexpect.EOF:
2397 main.log.error( self.name + ": EOF exception found" )
2398 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002399 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002400 except Exception:
2401 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002402 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002403
You Wang66518af2016-05-16 15:32:59 -07002404 def compareIntent( self, intentDict ):
2405 """
2406 Description:
2407 Compare the intent ids and states provided in the argument with all intents in ONOS
2408 Return:
2409 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2410 Arguments:
2411 intentDict: a dictionary which maps intent ids to intent states
2412 """
2413 try:
2414 intentsRaw = self.intents()
2415 intentsJson = json.loads( intentsRaw )
2416 intentDictONOS = {}
2417 for intent in intentsJson:
2418 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002419 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002420 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002421 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002422 str( len( intentDict ) ) + " expected and " +
2423 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002424 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002425 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002426 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002427 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2428 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002429 else:
2430 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2431 main.log.debug( self.name + ": intent ID - " + intentID +
2432 " expected state is " + intentDict[ intentID ] +
2433 " but actual state is " + intentDictONOS[ intentID ] )
2434 returnValue = main.FALSE
2435 intentDictONOS.pop( intentID )
2436 if len( intentDictONOS ) > 0:
2437 returnValue = main.FALSE
2438 for intentID in intentDictONOS.keys():
2439 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002440 if returnValue == main.TRUE:
2441 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2442 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002443 except KeyError:
2444 main.log.exception( self.name + ": KeyError exception found" )
2445 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002446 except ( TypeError, ValueError ):
2447 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002448 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002449 except pexpect.EOF:
2450 main.log.error( self.name + ": EOF exception found" )
2451 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002452 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002453 except Exception:
2454 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002455 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002456
YPZhang14a4aa92016-07-15 13:37:15 -07002457 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002458 """
2459 Description:
2460 Check the number of installed intents.
2461 Optional:
2462 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002463 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002464 Return:
2465 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2466 , otherwise, returns main.FALSE.
2467 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002468
GlennRCed771242016-01-13 17:02:47 -08002469 try:
2470 cmd = "intents -s -j"
2471
2472 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002473 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002474 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002475 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002476 response = json.loads( response )
2477
2478 # get total and installed number, see if they are match
2479 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002480 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002481 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2482 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002483 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002484 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2485 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002486 return main.FALSE
2487
Jon Hallc6793552016-01-19 14:18:37 -08002488 except ( TypeError, ValueError ):
2489 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002490 return None
2491 except pexpect.EOF:
2492 main.log.error( self.name + ": EOF exception found" )
2493 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002494 if noExit:
2495 return main.FALSE
2496 else:
Devin Lim44075962017-08-11 10:56:37 -07002497 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002498 except pexpect.TIMEOUT:
2499 main.log.error( self.name + ": ONOS timeout" )
2500 return None
GlennRCed771242016-01-13 17:02:47 -08002501 except Exception:
2502 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002503 if noExit:
2504 return main.FALSE
2505 else:
Devin Lim44075962017-08-11 10:56:37 -07002506 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002507
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002508 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002509 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002510 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002511 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002512 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002513 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002514 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002515 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002516 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002517 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002518 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002519 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002520 if noCore:
2521 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002522 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002523 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002524 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002525 assert "Command not found:" not in handle, handle
2526 if re.search( "Error:", handle ):
2527 main.log.error( self.name + ": flows() response: " +
2528 str( handle ) )
2529 return handle
2530 except AssertionError:
2531 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002532 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002533 except TypeError:
2534 main.log.exception( self.name + ": Object not as expected" )
2535 return None
Jon Hallc6793552016-01-19 14:18:37 -08002536 except pexpect.TIMEOUT:
2537 main.log.error( self.name + ": ONOS timeout" )
2538 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002539 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002540 main.log.error( self.name + ": EOF exception found" )
2541 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002542 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002543 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002544 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002545 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002546
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002547 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002548 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002549 count = int( count ) if count else 0
2550 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002551
Jon Halle0f0b342017-04-18 11:43:47 -07002552 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002553 """
2554 Description:
GlennRCed771242016-01-13 17:02:47 -08002555 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002556 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2557 if the count of those states is 0, which means all current flows
2558 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002559 Optional:
GlennRCed771242016-01-13 17:02:47 -08002560 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002561 Return:
2562 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002563 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002564 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002565 """
2566 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002567 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002568 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002569 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002570 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002571 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002572 if rawFlows:
2573 # if we didn't get flows or flows function return None, we should return
2574 # main.Flase
2575 checkedStates.append( json.loads( rawFlows ) )
2576 else:
2577 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002578 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002579 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002580 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002581 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002582 except TypeError:
2583 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002584 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002585
GlennRCed771242016-01-13 17:02:47 -08002586 # We want to count PENDING_ADD if isPENDING is true
2587 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002588 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002589 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002590 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002591 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002592 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002593 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002594 except ( TypeError, ValueError ):
2595 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002596 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002597
YPZhang240842b2016-05-17 12:00:50 -07002598 except AssertionError:
2599 main.log.exception( "" )
2600 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002601 except pexpect.TIMEOUT:
2602 main.log.error( self.name + ": ONOS timeout" )
2603 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002604 except pexpect.EOF:
2605 main.log.error( self.name + ": EOF exception found" )
2606 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002607 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002608 except Exception:
2609 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002610 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002611
GlennRCed771242016-01-13 17:02:47 -08002612 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002613 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002614 """
andrewonlab87852b02014-11-19 18:44:19 -05002615 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002616 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002617 a specific point-to-point intent definition
2618 Required:
GlennRCed771242016-01-13 17:02:47 -08002619 * ingress: specify source dpid
2620 * egress: specify destination dpid
2621 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002622 Optional:
GlennRCed771242016-01-13 17:02:47 -08002623 * offset: the keyOffset is where the next batch of intents
2624 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002625 * noExit: If set to True, TestON will not exit if any error when issus command
2626 * getResponse: If set to True, function will return ONOS response.
2627
GlennRCed771242016-01-13 17:02:47 -08002628 Returns: If failed to push test intents, it will returen None,
2629 if successful, return true.
2630 Timeout expection will return None,
2631 TypeError will return false
2632 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002633 """
andrewonlab87852b02014-11-19 18:44:19 -05002634 try:
GlennRCed771242016-01-13 17:02:47 -08002635 if background:
2636 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002637 else:
GlennRCed771242016-01-13 17:02:47 -08002638 back = ""
2639 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002640 ingress,
2641 egress,
2642 batchSize,
2643 offset,
2644 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002645 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002646 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002647 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002648 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002649 if getResponse:
2650 return response
2651
GlennRCed771242016-01-13 17:02:47 -08002652 # TODO: We should handle if there is failure in installation
2653 return main.TRUE
2654
Jon Hallc6793552016-01-19 14:18:37 -08002655 except AssertionError:
2656 main.log.exception( "" )
2657 return None
GlennRCed771242016-01-13 17:02:47 -08002658 except pexpect.TIMEOUT:
2659 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002660 return None
andrewonlab87852b02014-11-19 18:44:19 -05002661 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002662 main.log.error( self.name + ": EOF exception found" )
2663 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002664 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002665 except TypeError:
2666 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002667 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002668 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002669 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002670 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002671
YPZhangebf9eb52016-05-12 15:20:24 -07002672 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002673 """
2674 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002675 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002676 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002677 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002678 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002679 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002680
YPZhangb5d3f832016-01-23 22:54:26 -08002681 try:
YPZhange3109a72016-02-02 11:25:37 -08002682 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002683 cmd = "flows -c added"
2684 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2685 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002686 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002687 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002688 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002689 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002690 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002691 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002692 return None
2693 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002694
You Wangd3cb2ce2016-05-16 14:01:24 -07002695 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002696 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002697 return None
2698 except pexpect.EOF:
2699 main.log.error( self.name + ": EOF exception found" )
2700 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002701 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002702 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002703 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002704 except pexpect.TIMEOUT:
2705 main.log.error( self.name + ": ONOS timeout" )
2706 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002707 except Exception:
2708 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002709 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002710 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002711 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002712
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002713 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002714 """
2715 Description:
2716 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002717 Optional:
2718 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002719 Return:
2720 The number of intents
2721 """
2722 try:
2723 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002724 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002725 if response is None:
2726 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002727 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002728 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002729 except ( TypeError, ValueError ):
2730 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002731 return None
2732 except pexpect.EOF:
2733 main.log.error( self.name + ": EOF exception found" )
2734 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002735 if noExit:
2736 return -1
2737 else:
Devin Lim44075962017-08-11 10:56:37 -07002738 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002739 except Exception:
2740 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002741 if noExit:
2742 return -1
2743 else:
Devin Lim44075962017-08-11 10:56:37 -07002744 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002745
kelvin-onlabd3b64892015-01-20 13:26:24 -08002746 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002747 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002748 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002749 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002750 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002751 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002752 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002753 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002754 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002755 cmdStr += " -j"
2756 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002757 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002758 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002759 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002760 except AssertionError:
2761 main.log.exception( "" )
2762 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002763 except TypeError:
2764 main.log.exception( self.name + ": Object not as expected" )
2765 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002766 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002767 main.log.error( self.name + ": EOF exception found" )
2768 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002769 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002770 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002771 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002772 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002773
kelvin-onlabd3b64892015-01-20 13:26:24 -08002774 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002775 """
2776 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002777 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002778 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002779 """
andrewonlab867212a2014-10-22 20:13:38 -04002780 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002781 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002782 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002783 cmdStr += " -j"
2784 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002785 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002786 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002787 if handle:
2788 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002789 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002790 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002791 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002792 else:
2793 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002794 except AssertionError:
2795 main.log.exception( "" )
2796 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002797 except TypeError:
2798 main.log.exception( self.name + ": Object not as expected" )
2799 return None
andrewonlab867212a2014-10-22 20:13:38 -04002800 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002801 main.log.error( self.name + ": EOF exception found" )
2802 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002803 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002804 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002805 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002806 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002807
kelvin8ec71442015-01-15 16:57:00 -08002808 # Wrapper functions ****************
2809 # Wrapper functions use existing driver
2810 # functions and extends their use case.
2811 # For example, we may use the output of
2812 # a normal driver function, and parse it
2813 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002814
kelvin-onlabd3b64892015-01-20 13:26:24 -08002815 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002816 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002817 Description:
2818 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002819 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002820 try:
kelvin8ec71442015-01-15 16:57:00 -08002821 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002822 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002823 if intentsStr is None:
2824 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002825 # Convert to a dictionary
2826 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002827 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002828 for intent in intents:
2829 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002830 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002831 except TypeError:
2832 main.log.exception( self.name + ": Object not as expected" )
2833 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002834 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002835 main.log.error( self.name + ": EOF exception found" )
2836 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002837 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002838 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002839 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002840 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002841
You Wang3c276252016-09-21 15:21:36 -07002842 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002843 """
2844 Determine the number of flow rules for the given device id that are
2845 in the added state
You Wang3c276252016-09-21 15:21:36 -07002846 Params:
2847 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002848 """
2849 try:
You Wang3c276252016-09-21 15:21:36 -07002850 if core:
2851 cmdStr = "flows any " + str( deviceId ) + " | " +\
2852 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2853 else:
2854 cmdStr = "flows any " + str( deviceId ) + " | " +\
2855 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002856 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002857 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002858 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002859 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002860 except AssertionError:
2861 main.log.exception( "" )
2862 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002863 except pexpect.EOF:
2864 main.log.error( self.name + ": EOF exception found" )
2865 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002866 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002867 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002868 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002869 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002870
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002871 def groupAddedCount( self, deviceId, core=False ):
2872 """
2873 Determine the number of group rules for the given device id that are
2874 in the added state
2875 Params:
2876 core: if True, only return the number of core groups added
2877 """
2878 try:
2879 if core:
2880 cmdStr = "groups any " + str( deviceId ) + " | " +\
2881 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2882 else:
2883 cmdStr = "groups any " + str( deviceId ) + " | " +\
2884 "grep 'state=ADDED' | wc -l"
2885 handle = self.sendline( cmdStr )
2886 assert handle is not None, "Error in sendline"
2887 assert "Command not found:" not in handle, handle
2888 return handle
2889 except AssertionError:
2890 main.log.exception( "" )
2891 return None
2892 except pexpect.EOF:
2893 main.log.error( self.name + ": EOF exception found" )
2894 main.log.error( self.name + ": " + self.handle.before )
2895 main.cleanAndExit()
2896 except Exception:
2897 main.log.exception( self.name + ": Uncaught exception!" )
2898 main.cleanAndExit()
2899
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002900 def addStaticRoute( self, subnet, intf):
2901 """
2902 Adds a static route to onos.
2903 Params:
2904 subnet: The subnet reaching through this route
2905 intf: The interface this route is reachable through
2906 """
2907 try:
2908 cmdStr = "route-add " + subnet + " " + intf
2909 handle = self.sendline( cmdStr )
2910 assert handle is not None, "Error in sendline"
2911 assert "Command not found:" not in handle, handle
2912 return handle
2913 except AssertionError:
2914 main.log.exception( "" )
2915 return None
2916 except pexpect.EOF:
2917 main.log.error( self.name + ": EOF exception found" )
2918 main.log.error( self.name + ": " + self.handle.before )
2919 main.cleanAndExit()
2920 except Exception:
2921 main.log.exception( self.name + ": Uncaught exception!" )
2922 main.cleanAndExit()
2923
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002924 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
2925 """
2926 Description:
2927 Check whether the number of groups for the given device id that
2928 are in ADDED state is bigger than minGroupCount.
2929 Required:
2930 * deviceId: device id to check the number of added group rules
2931 Optional:
2932 * minGroupCount: the number of groups to compare
2933 * core: if True, only check the number of core groups added
2934 * comparison: if 0, compare with greater than minFlowCount
2935 * if 1, compare with equal to minFlowCount
2936 Return:
2937 Returns the number of groups if it is bigger than minGroupCount,
2938 returns main.FALSE otherwise.
2939 """
2940 count = self.groupAddedCount( deviceId, core )
2941 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07002942 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002943 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
2944
2945 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002946 """
2947 Description:
2948 Check whether the number of flow rules for the given device id that
2949 are in ADDED state is bigger than minFlowCount.
2950 Required:
2951 * deviceId: device id to check the number of added flow rules
2952 Optional:
2953 * minFlowCount: the number of flow rules to compare
2954 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002955 * comparison: if 0, compare with greater than minFlowCount
2956 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002957 Return:
2958 Returns the number of flow rules if it is bigger than minFlowCount,
2959 returns main.FALSE otherwise.
2960 """
2961 count = self.flowAddedCount( deviceId, core )
2962 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07002963 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002964 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002965
kelvin-onlabd3b64892015-01-20 13:26:24 -08002966 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002967 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002968 Use 'devices' function to obtain list of all devices
2969 and parse the result to obtain a list of all device
2970 id's. Returns this list. Returns empty list if no
2971 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002972 List is ordered sequentially
2973
andrewonlab3e15ead2014-10-15 14:21:34 -04002974 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002975 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002976 the ids. By obtaining the list of device ids on the fly,
2977 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002978 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002979 try:
kelvin8ec71442015-01-15 16:57:00 -08002980 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002981 devicesStr = self.devices( jsonFormat=False )
2982 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002983
kelvin-onlabd3b64892015-01-20 13:26:24 -08002984 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002985 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002986 return idList
kelvin8ec71442015-01-15 16:57:00 -08002987
2988 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002989 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002990 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002991 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002992 # Split list further into arguments before and after string
2993 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002994 # append to idList
2995 for arg in tempList:
2996 idList.append( arg.split( "id=" )[ 1 ] )
2997 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002998
Jon Halld4d4b372015-01-28 16:02:41 -08002999 except TypeError:
3000 main.log.exception( self.name + ": Object not as expected" )
3001 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003002 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003003 main.log.error( self.name + ": EOF exception found" )
3004 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003005 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003006 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003007 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003008 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003009
kelvin-onlabd3b64892015-01-20 13:26:24 -08003010 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003011 """
andrewonlab7c211572014-10-15 16:45:20 -04003012 Uses 'nodes' function to obtain list of all nodes
3013 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003014 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003015 Returns:
3016 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003017 """
andrewonlab7c211572014-10-15 16:45:20 -04003018 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003019 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003020 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003021 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003022 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003023 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003024 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003025 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003026 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003027 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003028 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003029 except ( TypeError, ValueError ):
3030 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003031 return None
andrewonlab7c211572014-10-15 16:45:20 -04003032 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003033 main.log.error( self.name + ": EOF exception found" )
3034 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003035 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003036 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003037 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003038 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003039
kelvin-onlabd3b64892015-01-20 13:26:24 -08003040 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003041 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003042 Return the first device from the devices api whose 'id' contains 'dpid'
3043 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003044 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003045 try:
kelvin8ec71442015-01-15 16:57:00 -08003046 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003047 return None
3048 else:
kelvin8ec71442015-01-15 16:57:00 -08003049 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003050 rawDevices = self.devices()
3051 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003052 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003053 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003054 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3055 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003056 return device
3057 return None
Jon Hallc6793552016-01-19 14:18:37 -08003058 except ( TypeError, ValueError ):
3059 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003060 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003061 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003062 main.log.error( self.name + ": EOF exception found" )
3063 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003064 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003065 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003066 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003067 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003068
You Wang24139872016-05-03 11:48:47 -07003069 def getTopology( self, topologyOutput ):
3070 """
3071 Definition:
3072 Loads a json topology output
3073 Return:
3074 topology = current ONOS topology
3075 """
3076 import json
3077 try:
3078 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003079 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003080 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003081 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003082 except ( TypeError, ValueError ):
3083 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3084 return None
You Wang24139872016-05-03 11:48:47 -07003085 except pexpect.EOF:
3086 main.log.error( self.name + ": EOF exception found" )
3087 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003088 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003089 except Exception:
3090 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003091 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003092
Pier6a0c4de2018-03-18 16:01:30 -07003093 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003094 """
Jon Hallefbd9792015-03-05 16:11:36 -08003095 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003096 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003097 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003098
Flavio Castro82ee2f62016-06-07 15:04:12 -07003099 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003100 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003101 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003102 logLevel = level to log to.
3103 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003104
Jon Hallefbd9792015-03-05 16:11:36 -08003105 Returns: main.TRUE if the number of switches and links are correct,
3106 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003107 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003108 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003109 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003110 try:
You Wang13310252016-07-31 10:56:14 -07003111 summary = self.summary()
3112 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003113 except ( TypeError, ValueError ):
3114 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3115 return main.ERROR
3116 try:
3117 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003118 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003119 return main.ERROR
3120 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003121 # Is the number of switches is what we expected
3122 devices = topology.get( 'devices', False )
3123 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003124 nodes = summary.get( 'nodes', False )
3125 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003126 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003127 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003128 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003129 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003130 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3131 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003132 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003133 output = output + "The number of links and switches match "\
3134 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003135 result = main.TRUE
3136 else:
You Wang24139872016-05-03 11:48:47 -07003137 output = output + \
3138 "The number of links and switches does not match " + \
3139 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003140 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003141 output = output + "\n ONOS sees %i devices" % int( devices )
3142 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003143 if int( numolink ) > 0:
3144 output = output + "and %i links " % int( links )
3145 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003146 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003147 output = output + "and %i controllers " % int( nodes )
3148 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003149 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003150 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003151 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003152 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003153 else:
You Wang24139872016-05-03 11:48:47 -07003154 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003155 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003156 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003157 main.log.error( self.name + ": EOF exception found" )
3158 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003159 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003160 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003161 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003162 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003163
kelvin-onlabd3b64892015-01-20 13:26:24 -08003164 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003165 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003166 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003167 deviceId must be the id of a device as seen in the onos devices command
3168 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003169 role must be either master, standby, or none
3170
Jon Halle3f39ff2015-01-13 11:50:53 -08003171 Returns:
3172 main.TRUE or main.FALSE based on argument verification and
3173 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003174 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003175 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003176 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003177 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003178 cmdStr = "device-role " +\
3179 str( deviceId ) + " " +\
3180 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003181 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003182 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003183 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003184 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003185 if re.search( "Error", handle ):
3186 # end color output to escape any colours
3187 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003188 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003189 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003190 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003191 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003192 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003193 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003194 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003195 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003196 except AssertionError:
3197 main.log.exception( "" )
3198 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003199 except TypeError:
3200 main.log.exception( self.name + ": Object not as expected" )
3201 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003202 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003203 main.log.error( self.name + ": EOF exception found" )
3204 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003205 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003206 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003207 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003208 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003209
kelvin-onlabd3b64892015-01-20 13:26:24 -08003210 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003211 """
Jon Hall0dd09952018-04-19 09:59:11 -07003212 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003213 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003214 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003215 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003216 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003217 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003218 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003219 cmdStr += " -j"
3220 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003221 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003222 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003223 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003224 except AssertionError:
3225 main.log.exception( "" )
3226 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003227 except TypeError:
3228 main.log.exception( self.name + ": Object not as expected" )
3229 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003230 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003231 main.log.error( self.name + ": EOF exception found" )
3232 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003233 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003234 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003235 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003236 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003237
kelvin-onlabd3b64892015-01-20 13:26:24 -08003238 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003239 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003240 CLI command to get the current leader for the Election test application
3241 NOTE: Requires installation of the onos-app-election feature
3242 Returns: Node IP of the leader if one exists
3243 None if none exists
3244 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003245 """
Jon Hall94fd0472014-12-08 11:52:42 -08003246 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003247 cmdStr = "election-test-leader"
3248 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003249 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003250 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003251 # Leader
3252 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003253 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003254 nodeSearch = re.search( leaderPattern, response )
3255 if nodeSearch:
3256 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003257 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003258 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003259 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003260 # no leader
3261 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003262 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003263 nullSearch = re.search( nullPattern, response )
3264 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003265 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003266 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003267 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003268 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003269 main.log.error( "Error in electionTestLeader on " + self.name +
3270 ": " + "unexpected response" )
3271 main.log.error( repr( response ) )
3272 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003273 except AssertionError:
3274 main.log.exception( "" )
3275 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003276 except TypeError:
3277 main.log.exception( self.name + ": Object not as expected" )
3278 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003279 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003280 main.log.error( self.name + ": EOF exception found" )
3281 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003282 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003283 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003284 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003285 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003286
kelvin-onlabd3b64892015-01-20 13:26:24 -08003287 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003288 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003289 CLI command to run for leadership of the Election test application.
3290 NOTE: Requires installation of the onos-app-election feature
3291 Returns: Main.TRUE on success
3292 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003293 """
Jon Hall94fd0472014-12-08 11:52:42 -08003294 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003295 cmdStr = "election-test-run"
3296 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003297 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003298 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003299 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003300 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003301 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003302 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003303 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003304 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003305 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003306 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003307 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003308 main.log.error( "Error in electionTestRun on " + self.name +
3309 ": " + "unexpected response" )
3310 main.log.error( repr( response ) )
3311 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003312 except AssertionError:
3313 main.log.exception( "" )
3314 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003315 except TypeError:
3316 main.log.exception( self.name + ": Object not as expected" )
3317 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003318 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003319 main.log.error( self.name + ": EOF exception found" )
3320 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003321 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003322 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003323 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003324 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003325
kelvin-onlabd3b64892015-01-20 13:26:24 -08003326 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003327 """
Jon Hall94fd0472014-12-08 11:52:42 -08003328 * CLI command to withdraw the local node from leadership election for
3329 * the Election test application.
3330 #NOTE: Requires installation of the onos-app-election feature
3331 Returns: Main.TRUE on success
3332 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003333 """
Jon Hall94fd0472014-12-08 11:52:42 -08003334 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003335 cmdStr = "election-test-withdraw"
3336 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003337 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003338 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003339 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003340 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003341 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003342 if re.search( successPattern, response ):
3343 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003344 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003345 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003346 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003347 main.log.error( "Error in electionTestWithdraw on " +
3348 self.name + ": " + "unexpected response" )
3349 main.log.error( repr( response ) )
3350 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003351 except AssertionError:
3352 main.log.exception( "" )
3353 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003354 except TypeError:
3355 main.log.exception( self.name + ": Object not as expected" )
3356 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003357 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003358 main.log.error( self.name + ": EOF exception found" )
3359 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003360 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003361 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003362 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003363 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003364
kelvin8ec71442015-01-15 16:57:00 -08003365 def getDevicePortsEnabledCount( self, dpid ):
3366 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003367 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003368 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003369 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003370 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003371 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3372 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003373 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003374 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003375 if re.search( "No such device", output ):
3376 main.log.error( "Error in getting ports" )
3377 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003378 return output
Jon Hallc6793552016-01-19 14:18:37 -08003379 except AssertionError:
3380 main.log.exception( "" )
3381 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003382 except TypeError:
3383 main.log.exception( self.name + ": Object not as expected" )
3384 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003385 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003386 main.log.error( self.name + ": EOF exception found" )
3387 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003388 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003389 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003390 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003391 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003392
kelvin8ec71442015-01-15 16:57:00 -08003393 def getDeviceLinksActiveCount( self, dpid ):
3394 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003395 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003396 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003397 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003398 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003399 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3400 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003401 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003402 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003403 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003404 main.log.error( "Error in getting ports " )
3405 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003406 return output
Jon Hallc6793552016-01-19 14:18:37 -08003407 except AssertionError:
3408 main.log.exception( "" )
3409 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003410 except TypeError:
3411 main.log.exception( self.name + ": Object not as expected" )
3412 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003413 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003414 main.log.error( self.name + ": EOF exception found" )
3415 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003416 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003417 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003418 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003419 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003420
kelvin8ec71442015-01-15 16:57:00 -08003421 def getAllIntentIds( self ):
3422 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003423 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003424 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003425 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003426 cmdStr = "onos:intents | grep id="
3427 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003428 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003429 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003430 if re.search( "Error", output ):
3431 main.log.error( "Error in getting ports" )
3432 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003433 return output
Jon Hallc6793552016-01-19 14:18:37 -08003434 except AssertionError:
3435 main.log.exception( "" )
3436 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003437 except TypeError:
3438 main.log.exception( self.name + ": Object not as expected" )
3439 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003440 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003441 main.log.error( self.name + ": EOF exception found" )
3442 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003443 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003444 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003445 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003446 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003447
Jon Hall73509952015-02-24 16:42:56 -08003448 def intentSummary( self ):
3449 """
Jon Hallefbd9792015-03-05 16:11:36 -08003450 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003451 """
3452 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003453 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003454 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003455 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003456 states.append( intent.get( 'state', None ) )
3457 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003458 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003459 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003460 except ( TypeError, ValueError ):
3461 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003462 return None
3463 except pexpect.EOF:
3464 main.log.error( self.name + ": EOF exception found" )
3465 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003466 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003467 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003468 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003469 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003470
Jon Hall61282e32015-03-19 11:34:11 -07003471 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003472 """
3473 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003474 Optional argument:
3475 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003476 """
Jon Hall63604932015-02-26 17:09:50 -08003477 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003478 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003479 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003480 cmdStr += " -j"
3481 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003482 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003483 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003484 return output
Jon Hallc6793552016-01-19 14:18:37 -08003485 except AssertionError:
3486 main.log.exception( "" )
3487 return None
Jon Hall63604932015-02-26 17:09:50 -08003488 except TypeError:
3489 main.log.exception( self.name + ": Object not as expected" )
3490 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003491 except pexpect.EOF:
3492 main.log.error( self.name + ": EOF exception found" )
3493 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003494 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003495 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003496 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003497 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003498
acsmarsa4a4d1e2015-07-10 16:01:24 -07003499 def leaderCandidates( self, jsonFormat=True ):
3500 """
3501 Returns the output of the leaders -c command.
3502 Optional argument:
3503 * jsonFormat - boolean indicating if you want output in json
3504 """
3505 try:
3506 cmdStr = "onos:leaders -c"
3507 if jsonFormat:
3508 cmdStr += " -j"
3509 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003510 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003511 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003512 return output
Jon Hallc6793552016-01-19 14:18:37 -08003513 except AssertionError:
3514 main.log.exception( "" )
3515 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003516 except TypeError:
3517 main.log.exception( self.name + ": Object not as expected" )
3518 return None
3519 except pexpect.EOF:
3520 main.log.error( self.name + ": EOF exception found" )
3521 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003522 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003523 except Exception:
3524 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003525 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003526
Jon Hallc6793552016-01-19 14:18:37 -08003527 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003528 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003529 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003530 topic parameter and an empty list if the topic doesn't exist
3531 If no leader is elected leader in the returned list will be "none"
3532 Returns None if there is a type error processing the json object
3533 """
3534 try:
Jon Hall6e709752016-02-01 13:38:46 -08003535 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003536 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003537 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003538 assert "Command not found:" not in rawOutput, rawOutput
3539 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003540 results = []
3541 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003542 if dict[ "topic" ] == topic:
3543 leader = dict[ "leader" ]
3544 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003545 results.append( leader )
3546 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003547 return results
Jon Hallc6793552016-01-19 14:18:37 -08003548 except AssertionError:
3549 main.log.exception( "" )
3550 return None
3551 except ( TypeError, ValueError ):
3552 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003553 return None
3554 except pexpect.EOF:
3555 main.log.error( self.name + ": EOF exception found" )
3556 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003557 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003558 except Exception:
3559 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003560 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003561
Jon Hall61282e32015-03-19 11:34:11 -07003562 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003563 """
3564 Returns the output of the intent Pending map.
3565 """
Jon Hall63604932015-02-26 17:09:50 -08003566 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003567 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003568 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003569 cmdStr += " -j"
3570 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003571 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003572 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003573 return output
Jon Hallc6793552016-01-19 14:18:37 -08003574 except AssertionError:
3575 main.log.exception( "" )
3576 return None
Jon Hall63604932015-02-26 17:09:50 -08003577 except TypeError:
3578 main.log.exception( self.name + ": Object not as expected" )
3579 return None
3580 except pexpect.EOF:
3581 main.log.error( self.name + ": EOF exception found" )
3582 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003583 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003584 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003585 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003586 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003587
Jon Hall2c8959e2016-12-16 12:17:34 -08003588 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003589 """
3590 Returns the output of the raft partitions command for ONOS.
3591 """
Jon Hall61282e32015-03-19 11:34:11 -07003592 # Sample JSON
3593 # {
3594 # "leader": "tcp://10.128.30.11:7238",
3595 # "members": [
3596 # "tcp://10.128.30.11:7238",
3597 # "tcp://10.128.30.17:7238",
3598 # "tcp://10.128.30.13:7238",
3599 # ],
3600 # "name": "p1",
3601 # "term": 3
3602 # },
Jon Hall63604932015-02-26 17:09:50 -08003603 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003604 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003605 if candidates:
3606 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003607 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003608 cmdStr += " -j"
3609 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003610 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003611 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003612 return output
Jon Hallc6793552016-01-19 14:18:37 -08003613 except AssertionError:
3614 main.log.exception( "" )
3615 return None
Jon Hall63604932015-02-26 17:09:50 -08003616 except TypeError:
3617 main.log.exception( self.name + ": Object not as expected" )
3618 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()
Jon Hall77ba41c2015-04-06 10:25:40 -07003623 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003624 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003625 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003626
Jon Halle9f909e2016-09-23 10:43:12 -07003627 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003628 """
3629 Returns the output of the apps command for ONOS. This command lists
3630 information about installed ONOS applications
3631 """
3632 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003633 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003634 # "description":"ONOS OpenFlow protocol southbound providers",
3635 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003636 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003637 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003638 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003639 if summary:
3640 cmdStr += " -s"
3641 if active:
3642 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003643 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003644 cmdStr += " -j"
3645 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003646 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003647 assert "Command not found:" not in output, output
3648 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003649 return output
Jon Hallbe379602015-03-24 13:39:32 -07003650 # FIXME: look at specific exceptions/Errors
3651 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003652 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003653 return None
3654 except TypeError:
3655 main.log.exception( self.name + ": Object not as expected" )
3656 return None
3657 except pexpect.EOF:
3658 main.log.error( self.name + ": EOF exception found" )
3659 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003660 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003661 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003662 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003663 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003664
Jon Hall146f1522015-03-24 15:33:24 -07003665 def appStatus( self, appName ):
3666 """
3667 Uses the onos:apps cli command to return the status of an application.
3668 Returns:
3669 "ACTIVE" - If app is installed and activated
3670 "INSTALLED" - If app is installed and deactivated
3671 "UNINSTALLED" - If app is not installed
3672 None - on error
3673 """
Jon Hall146f1522015-03-24 15:33:24 -07003674 try:
3675 if not isinstance( appName, types.StringType ):
3676 main.log.error( self.name + ".appStatus(): appName must be" +
3677 " a string" )
3678 return None
3679 output = self.apps( jsonFormat=True )
3680 appsJson = json.loads( output )
3681 state = None
3682 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003683 if appName == app.get( 'name' ):
3684 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003685 break
3686 if state == "ACTIVE" or state == "INSTALLED":
3687 return state
3688 elif state is None:
Jon Hall8bafdc02017-09-05 11:36:26 -07003689 main.log.warn( "{} app not found", appName )
Jon Hall146f1522015-03-24 15:33:24 -07003690 return "UNINSTALLED"
3691 elif state:
3692 main.log.error( "Unexpected state from 'onos:apps': " +
3693 str( state ) )
3694 return state
Jon Hallc6793552016-01-19 14:18:37 -08003695 except ( TypeError, ValueError ):
3696 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003697 return None
3698 except pexpect.EOF:
3699 main.log.error( self.name + ": EOF exception found" )
3700 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003701 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003702 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003703 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003704 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003705
Jon Hallbe379602015-03-24 13:39:32 -07003706 def app( self, appName, option ):
3707 """
3708 Interacts with the app command for ONOS. This command manages
3709 application inventory.
3710 """
Jon Hallbe379602015-03-24 13:39:32 -07003711 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003712 # Validate argument types
3713 valid = True
3714 if not isinstance( appName, types.StringType ):
3715 main.log.error( self.name + ".app(): appName must be a " +
3716 "string" )
3717 valid = False
3718 if not isinstance( option, types.StringType ):
3719 main.log.error( self.name + ".app(): option must be a string" )
3720 valid = False
3721 if not valid:
3722 return main.FALSE
3723 # Validate Option
3724 option = option.lower()
3725 # NOTE: Install may become a valid option
3726 if option == "activate":
3727 pass
3728 elif option == "deactivate":
3729 pass
3730 elif option == "uninstall":
3731 pass
3732 else:
3733 # Invalid option
3734 main.log.error( "The ONOS app command argument only takes " +
3735 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003736 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003737 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003738 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003739 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003740 assert output is not None, "Error in sendline"
3741 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003742 if "Error executing command" in output:
3743 main.log.error( "Error in processing onos:app command: " +
3744 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003745 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003746 elif "No such application" in output:
3747 main.log.error( "The application '" + appName +
3748 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003749 return main.FALSE
3750 elif "Command not found:" in output:
3751 main.log.error( "Error in processing onos:app command: " +
3752 str( output ) )
3753 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003754 elif "Unsupported command:" in output:
3755 main.log.error( "Incorrect command given to 'app': " +
3756 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003757 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003758 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003759 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003760 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003761 except AssertionError:
3762 main.log.exception( self.name + ": AssertionError exception found" )
3763 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003764 except TypeError:
3765 main.log.exception( self.name + ": Object not as expected" )
3766 return main.ERROR
3767 except pexpect.EOF:
3768 main.log.error( self.name + ": EOF exception found" )
3769 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003770 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003771 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003772 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003773 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003774
Jon Hallbd16b922015-03-26 17:53:15 -07003775 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003776 """
3777 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003778 appName is the hierarchical app name, not the feature name
3779 If check is True, method will check the status of the app after the
3780 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003781 Returns main.TRUE if the command was successfully sent
3782 main.FALSE if the cli responded with an error or given
3783 incorrect input
3784 """
3785 try:
3786 if not isinstance( appName, types.StringType ):
3787 main.log.error( self.name + ".activateApp(): appName must be" +
3788 " a string" )
3789 return main.FALSE
3790 status = self.appStatus( appName )
3791 if status == "INSTALLED":
3792 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003793 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003794 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003795 status = self.appStatus( appName )
3796 if status == "ACTIVE":
3797 return main.TRUE
3798 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003799 main.log.debug( "The state of application " +
3800 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003801 time.sleep( 1 )
3802 return main.FALSE
3803 else: # not 'check' or command didn't succeed
3804 return response
Jon Hall146f1522015-03-24 15:33:24 -07003805 elif status == "ACTIVE":
3806 return main.TRUE
3807 elif status == "UNINSTALLED":
3808 main.log.error( self.name + ": Tried to activate the " +
3809 "application '" + appName + "' which is not " +
3810 "installed." )
3811 else:
3812 main.log.error( "Unexpected return value from appStatus: " +
3813 str( status ) )
3814 return main.ERROR
3815 except TypeError:
3816 main.log.exception( self.name + ": Object not as expected" )
3817 return main.ERROR
3818 except pexpect.EOF:
3819 main.log.error( self.name + ": EOF exception found" )
3820 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003821 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003822 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003823 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003824 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003825
Jon Hallbd16b922015-03-26 17:53:15 -07003826 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003827 """
3828 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003829 appName is the hierarchical app name, not the feature name
3830 If check is True, method will check the status of the app after the
3831 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003832 Returns main.TRUE if the command was successfully sent
3833 main.FALSE if the cli responded with an error or given
3834 incorrect input
3835 """
3836 try:
3837 if not isinstance( appName, types.StringType ):
3838 main.log.error( self.name + ".deactivateApp(): appName must " +
3839 "be a string" )
3840 return main.FALSE
3841 status = self.appStatus( appName )
3842 if status == "INSTALLED":
3843 return main.TRUE
3844 elif status == "ACTIVE":
3845 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003846 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003847 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003848 status = self.appStatus( appName )
3849 if status == "INSTALLED":
3850 return main.TRUE
3851 else:
3852 time.sleep( 1 )
3853 return main.FALSE
3854 else: # not check or command didn't succeed
3855 return response
Jon Hall146f1522015-03-24 15:33:24 -07003856 elif status == "UNINSTALLED":
3857 main.log.warn( self.name + ": Tried to deactivate the " +
3858 "application '" + appName + "' which is not " +
3859 "installed." )
3860 return main.TRUE
3861 else:
3862 main.log.error( "Unexpected return value from appStatus: " +
3863 str( status ) )
3864 return main.ERROR
3865 except TypeError:
3866 main.log.exception( self.name + ": Object not as expected" )
3867 return main.ERROR
3868 except pexpect.EOF:
3869 main.log.error( self.name + ": EOF exception found" )
3870 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003871 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003872 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003873 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003874 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003875
Jon Hallbd16b922015-03-26 17:53:15 -07003876 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003877 """
3878 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003879 appName is the hierarchical app name, not the feature name
3880 If check is True, method will check the status of the app after the
3881 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003882 Returns main.TRUE if the command was successfully sent
3883 main.FALSE if the cli responded with an error or given
3884 incorrect input
3885 """
3886 # TODO: check with Thomas about the state machine for apps
3887 try:
3888 if not isinstance( appName, types.StringType ):
3889 main.log.error( self.name + ".uninstallApp(): appName must " +
3890 "be a string" )
3891 return main.FALSE
3892 status = self.appStatus( appName )
3893 if status == "INSTALLED":
3894 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003895 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003896 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003897 status = self.appStatus( appName )
3898 if status == "UNINSTALLED":
3899 return main.TRUE
3900 else:
3901 time.sleep( 1 )
3902 return main.FALSE
3903 else: # not check or command didn't succeed
3904 return response
Jon Hall146f1522015-03-24 15:33:24 -07003905 elif status == "ACTIVE":
3906 main.log.warn( self.name + ": Tried to uninstall the " +
3907 "application '" + appName + "' which is " +
3908 "currently active." )
3909 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003910 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003911 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003912 status = self.appStatus( appName )
3913 if status == "UNINSTALLED":
3914 return main.TRUE
3915 else:
3916 time.sleep( 1 )
3917 return main.FALSE
3918 else: # not check or command didn't succeed
3919 return response
Jon Hall146f1522015-03-24 15:33:24 -07003920 elif status == "UNINSTALLED":
3921 return main.TRUE
3922 else:
3923 main.log.error( "Unexpected return value from appStatus: " +
3924 str( status ) )
3925 return main.ERROR
3926 except TypeError:
3927 main.log.exception( self.name + ": Object not as expected" )
3928 return main.ERROR
3929 except pexpect.EOF:
3930 main.log.error( self.name + ": EOF exception found" )
3931 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003932 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003933 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003934 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003935 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003936
3937 def appIDs( self, jsonFormat=True ):
3938 """
3939 Show the mappings between app id and app names given by the 'app-ids'
3940 cli command
3941 """
3942 try:
3943 cmdStr = "app-ids"
3944 if jsonFormat:
3945 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003946 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003947 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003948 assert "Command not found:" not in output, output
3949 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003950 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003951 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003952 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003953 return None
3954 except TypeError:
3955 main.log.exception( self.name + ": Object not as expected" )
3956 return None
3957 except pexpect.EOF:
3958 main.log.error( self.name + ": EOF exception found" )
3959 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003960 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003961 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003962 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003963 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003964
3965 def appToIDCheck( self ):
3966 """
3967 This method will check that each application's ID listed in 'apps' is
3968 the same as the ID listed in 'app-ids'. The check will also check that
3969 there are no duplicate IDs issued. Note that an app ID should be
3970 a globaly unique numerical identifier for app/app-like features. Once
3971 an ID is registered, the ID is never freed up so that if an app is
3972 reinstalled it will have the same ID.
3973
3974 Returns: main.TRUE if the check passes and
3975 main.FALSE if the check fails or
3976 main.ERROR if there is some error in processing the test
3977 """
3978 try:
Jon Hall390696c2015-05-05 17:13:41 -07003979 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003980 rawJson = self.appIDs( jsonFormat=True )
3981 if rawJson:
3982 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003983 else:
Jon Hallc6793552016-01-19 14:18:37 -08003984 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003985 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003986 rawJson = self.apps( jsonFormat=True )
3987 if rawJson:
3988 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003989 else:
Jon Hallc6793552016-01-19 14:18:37 -08003990 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003991 bail = True
3992 if bail:
3993 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003994 result = main.TRUE
3995 for app in apps:
3996 appID = app.get( 'id' )
3997 if appID is None:
3998 main.log.error( "Error parsing app: " + str( app ) )
3999 result = main.FALSE
4000 appName = app.get( 'name' )
4001 if appName is None:
4002 main.log.error( "Error parsing app: " + str( app ) )
4003 result = main.FALSE
4004 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004005 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004006 if not current: # if ids doesn't have this id
4007 result = main.FALSE
4008 main.log.error( "'app-ids' does not have the ID for " +
4009 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004010 main.log.debug( "apps command returned: " + str( app ) +
4011 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004012 elif len( current ) > 1:
4013 # there is more than one app with this ID
4014 result = main.FALSE
4015 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004016 elif not current[ 0 ][ 'name' ] == appName:
4017 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004018 result = main.FALSE
4019 main.log.error( "'app-ids' has " + str( currentName ) +
4020 " registered under id:" + str( appID ) +
4021 " but 'apps' has " + str( appName ) )
4022 else:
4023 pass # id and name match!
4024 # now make sure that app-ids has no duplicates
4025 idsList = []
4026 namesList = []
4027 for item in ids:
4028 idsList.append( item[ 'id' ] )
4029 namesList.append( item[ 'name' ] )
4030 if len( idsList ) != len( set( idsList ) ) or\
4031 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004032 main.log.error( "'app-ids' has some duplicate entries: \n"
4033 + json.dumps( ids,
4034 sort_keys=True,
4035 indent=4,
4036 separators=( ',', ': ' ) ) )
4037 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004038 return result
Jon Hallc6793552016-01-19 14:18:37 -08004039 except ( TypeError, ValueError ):
4040 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004041 return main.ERROR
4042 except pexpect.EOF:
4043 main.log.error( self.name + ": EOF exception found" )
4044 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004045 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004046 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004047 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004048 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004049
Jon Hallfb760a02015-04-13 15:35:03 -07004050 def getCfg( self, component=None, propName=None, short=False,
4051 jsonFormat=True ):
4052 """
4053 Get configuration settings from onos cli
4054 Optional arguments:
4055 component - Optionally only list configurations for a specific
4056 component. If None, all components with configurations
4057 are displayed. Case Sensitive string.
4058 propName - If component is specified, propName option will show
4059 only this specific configuration from that component.
4060 Case Sensitive string.
4061 jsonFormat - Returns output as json. Note that this will override
4062 the short option
4063 short - Short, less verbose, version of configurations.
4064 This is overridden by the json option
4065 returns:
4066 Output from cli as a string or None on error
4067 """
4068 try:
4069 baseStr = "cfg"
4070 cmdStr = " get"
4071 componentStr = ""
4072 if component:
4073 componentStr += " " + component
4074 if propName:
4075 componentStr += " " + propName
4076 if jsonFormat:
4077 baseStr += " -j"
4078 elif short:
4079 baseStr += " -s"
4080 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004081 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004082 assert "Command not found:" not in output, output
4083 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004084 return output
4085 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004086 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004087 return None
4088 except TypeError:
4089 main.log.exception( self.name + ": Object not as expected" )
4090 return None
4091 except pexpect.EOF:
4092 main.log.error( self.name + ": EOF exception found" )
4093 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004094 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004095 except Exception:
4096 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004097 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004098
4099 def setCfg( self, component, propName, value=None, check=True ):
4100 """
4101 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004102 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004103 component - The case sensitive name of the component whose
4104 property is to be set
4105 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004106 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004107 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004108 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004109 check - Boolean, Check whether the option was successfully set this
4110 only applies when a value is given.
4111 returns:
4112 main.TRUE on success or main.FALSE on failure. If check is False,
4113 will return main.TRUE unless there is an error
4114 """
4115 try:
4116 baseStr = "cfg"
4117 cmdStr = " set " + str( component ) + " " + str( propName )
4118 if value is not None:
4119 cmdStr += " " + str( value )
4120 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004121 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004122 assert "Command not found:" not in output, output
4123 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004124 if value and check:
4125 results = self.getCfg( component=str( component ),
4126 propName=str( propName ),
4127 jsonFormat=True )
4128 # Check if current value is what we just set
4129 try:
4130 jsonOutput = json.loads( results )
4131 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004132 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004133 main.log.exception( "Error parsing cfg output" )
4134 main.log.error( "output:" + repr( results ) )
4135 return main.FALSE
4136 if current == str( value ):
4137 return main.TRUE
4138 return main.FALSE
4139 return main.TRUE
4140 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004141 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004142 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004143 except ( TypeError, ValueError ):
4144 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004145 return main.FALSE
4146 except pexpect.EOF:
4147 main.log.error( self.name + ": EOF exception found" )
4148 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004149 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004150 except Exception:
4151 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004152 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004153
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004154 def distPrimitivesSend( self, cmd ):
4155 """
4156 Function to handle sending cli commands for the distributed primitives test app
4157
4158 This command will catch some exceptions and retry the command on some
4159 specific store exceptions.
4160
4161 Required arguments:
4162 cmd - The command to send to the cli
4163 returns:
4164 string containing the cli output
4165 None on Error
4166 """
4167 try:
4168 output = self.sendline( cmd )
4169 try:
4170 assert output is not None, "Error in sendline"
4171 # TODO: Maybe make this less hardcoded
4172 # ConsistentMap Exceptions
4173 assert "org.onosproject.store.service" not in output
4174 # Node not leader
4175 assert "java.lang.IllegalStateException" not in output
4176 except AssertionError:
4177 main.log.error( "Error in processing '" + cmd + "' " +
4178 "command: " + str( output ) )
4179 retryTime = 30 # Conservative time, given by Madan
4180 main.log.info( "Waiting " + str( retryTime ) +
4181 "seconds before retrying." )
4182 time.sleep( retryTime ) # Due to change in mastership
4183 output = self.sendline( cmd )
4184 assert output is not None, "Error in sendline"
4185 assert "Command not found:" not in output, output
4186 assert "Error executing command" not in output, output
4187 main.log.info( self.name + ": " + output )
4188 return output
4189 except AssertionError:
4190 main.log.exception( "Error in processing '" + cmd + "' command." )
4191 return None
4192 except TypeError:
4193 main.log.exception( self.name + ": Object not as expected" )
4194 return None
4195 except pexpect.EOF:
4196 main.log.error( self.name + ": EOF exception found" )
4197 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004198 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004199 except Exception:
4200 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004201 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004202
Jon Hall390696c2015-05-05 17:13:41 -07004203 def setTestAdd( self, setName, values ):
4204 """
4205 CLI command to add elements to a distributed set.
4206 Arguments:
4207 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004208 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004209 Example usages:
4210 setTestAdd( "set1", "a b c" )
4211 setTestAdd( "set2", "1" )
4212 returns:
4213 main.TRUE on success OR
4214 main.FALSE if elements were already in the set OR
4215 main.ERROR on error
4216 """
4217 try:
4218 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004219 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004220 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4221 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004222 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004223 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004224 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004225 return main.FALSE
4226 else:
4227 main.log.error( self.name + ": setTestAdd did not" +
4228 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004229 main.log.debug( self.name + " actual: " + repr( output ) )
4230 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004231 except TypeError:
4232 main.log.exception( self.name + ": Object not as expected" )
4233 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004234 except Exception:
4235 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004236 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004237
4238 def setTestRemove( self, setName, values, clear=False, retain=False ):
4239 """
4240 CLI command to remove elements from a distributed set.
4241 Required arguments:
4242 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004243 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004244 Optional arguments:
4245 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004246 retain - Retain only the given values. (intersection of the
4247 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004248 returns:
4249 main.TRUE on success OR
4250 main.FALSE if the set was not changed OR
4251 main.ERROR on error
4252 """
4253 try:
4254 cmdStr = "set-test-remove "
4255 if clear:
4256 cmdStr += "-c " + str( setName )
4257 elif retain:
4258 cmdStr += "-r " + str( setName ) + " " + str( values )
4259 else:
4260 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004261 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004262 if clear:
4263 pattern = "Set " + str( setName ) + " cleared"
4264 if re.search( pattern, output ):
4265 return main.TRUE
4266 elif retain:
4267 positivePattern = str( setName ) + " was pruned to contain " +\
4268 "only elements of set \[(.*)\]"
4269 negativePattern = str( setName ) + " was not changed by " +\
4270 "retaining only elements of the set " +\
4271 "\[(.*)\]"
4272 if re.search( positivePattern, output ):
4273 return main.TRUE
4274 elif re.search( negativePattern, output ):
4275 return main.FALSE
4276 else:
4277 positivePattern = "\[(.*)\] was removed from the set " +\
4278 str( setName )
4279 if ( len( values.split() ) == 1 ):
4280 negativePattern = "\[(.*)\] was not in set " +\
4281 str( setName )
4282 else:
4283 negativePattern = "No element of \[(.*)\] was in set " +\
4284 str( setName )
4285 if re.search( positivePattern, output ):
4286 return main.TRUE
4287 elif re.search( negativePattern, output ):
4288 return main.FALSE
4289 main.log.error( self.name + ": setTestRemove did not" +
4290 " match expected output" )
4291 main.log.debug( self.name + " expected: " + pattern )
4292 main.log.debug( self.name + " actual: " + repr( output ) )
4293 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004294 except TypeError:
4295 main.log.exception( self.name + ": Object not as expected" )
4296 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004297 except Exception:
4298 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004299 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004300
4301 def setTestGet( self, setName, values="" ):
4302 """
4303 CLI command to get the elements in a distributed set.
4304 Required arguments:
4305 setName - The name of the set to remove from.
4306 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004307 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004308 returns:
4309 main.ERROR on error OR
4310 A list of elements in the set if no optional arguments are
4311 supplied OR
4312 A tuple containing the list then:
4313 main.FALSE if the given values are not in the set OR
4314 main.TRUE if the given values are in the set OR
4315 """
4316 try:
4317 values = str( values ).strip()
4318 setName = str( setName ).strip()
4319 length = len( values.split() )
4320 containsCheck = None
4321 # Patterns to match
4322 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004323 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004324 containsTrue = "Set " + setName + " contains the value " + values
4325 containsFalse = "Set " + setName + " did not contain the value " +\
4326 values
4327 containsAllTrue = "Set " + setName + " contains the the subset " +\
4328 setPattern
4329 containsAllFalse = "Set " + setName + " did not contain the the" +\
4330 " subset " + setPattern
4331
4332 cmdStr = "set-test-get "
4333 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004334 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004335 if length == 0:
4336 match = re.search( pattern, output )
4337 else: # if given values
4338 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004339 patternTrue = pattern + "\r\n" + containsTrue
4340 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004341 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004342 patternTrue = pattern + "\r\n" + containsAllTrue
4343 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004344 matchTrue = re.search( patternTrue, output )
4345 matchFalse = re.search( patternFalse, output )
4346 if matchTrue:
4347 containsCheck = main.TRUE
4348 match = matchTrue
4349 elif matchFalse:
4350 containsCheck = main.FALSE
4351 match = matchFalse
4352 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004353 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004354 "expected output" )
4355 main.log.debug( self.name + " expected: " + pattern )
4356 main.log.debug( self.name + " actual: " + repr( output ) )
4357 match = None
4358 if match:
4359 setMatch = match.group( 1 )
4360 if setMatch == '':
4361 setList = []
4362 else:
4363 setList = setMatch.split( ", " )
4364 if length > 0:
4365 return ( setList, containsCheck )
4366 else:
4367 return setList
4368 else: # no match
4369 main.log.error( self.name + ": setTestGet did not" +
4370 " match expected output" )
4371 main.log.debug( self.name + " expected: " + pattern )
4372 main.log.debug( self.name + " actual: " + repr( output ) )
4373 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004374 except TypeError:
4375 main.log.exception( self.name + ": Object not as expected" )
4376 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004377 except Exception:
4378 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004379 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004380
4381 def setTestSize( self, setName ):
4382 """
4383 CLI command to get the elements in a distributed set.
4384 Required arguments:
4385 setName - The name of the set to remove from.
4386 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004387 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004388 None on error
4389 """
4390 try:
4391 # TODO: Should this check against the number of elements returned
4392 # and then return true/false based on that?
4393 setName = str( setName ).strip()
4394 # Patterns to match
4395 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004396 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004397 setPattern
4398 cmdStr = "set-test-get -s "
4399 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004400 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004401 match = re.search( pattern, output )
4402 if match:
4403 setSize = int( match.group( 1 ) )
4404 setMatch = match.group( 2 )
4405 if len( setMatch.split() ) == setSize:
4406 main.log.info( "The size returned by " + self.name +
4407 " matches the number of elements in " +
4408 "the returned set" )
4409 else:
4410 main.log.error( "The size returned by " + self.name +
4411 " does not match the number of " +
4412 "elements in the returned set." )
4413 return setSize
4414 else: # no match
4415 main.log.error( self.name + ": setTestGet did not" +
4416 " match expected output" )
4417 main.log.debug( self.name + " expected: " + pattern )
4418 main.log.debug( self.name + " actual: " + repr( output ) )
4419 return None
Jon Hall390696c2015-05-05 17:13:41 -07004420 except TypeError:
4421 main.log.exception( self.name + ": Object not as expected" )
4422 return None
Jon Hall390696c2015-05-05 17:13:41 -07004423 except Exception:
4424 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004425 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004426
Jon Hall80daded2015-05-27 16:07:00 -07004427 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004428 """
4429 Command to list the various counters in the system.
4430 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004431 if jsonFormat, a string of the json object returned by the cli
4432 command
4433 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004434 None on error
4435 """
Jon Hall390696c2015-05-05 17:13:41 -07004436 try:
Jon Hall390696c2015-05-05 17:13:41 -07004437 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004438 if jsonFormat:
4439 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004440 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004441 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004442 assert "Command not found:" not in output, output
4443 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004444 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004445 return output
Jon Hall390696c2015-05-05 17:13:41 -07004446 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004447 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004448 return None
Jon Hall390696c2015-05-05 17:13:41 -07004449 except TypeError:
4450 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004451 return None
Jon Hall390696c2015-05-05 17:13:41 -07004452 except pexpect.EOF:
4453 main.log.error( self.name + ": EOF exception found" )
4454 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004455 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004456 except Exception:
4457 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004458 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004459
Jon Hall935db192016-04-19 00:22:04 -07004460 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004461 """
Jon Halle1a3b752015-07-22 13:02:46 -07004462 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004463 Required arguments:
4464 counter - The name of the counter to increment.
4465 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004466 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004467 returns:
4468 integer value of the counter or
4469 None on Error
4470 """
4471 try:
4472 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004473 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004474 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004475 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004476 if delta != 1:
4477 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004478 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004479 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004480 match = re.search( pattern, output )
4481 if match:
4482 return int( match.group( 1 ) )
4483 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004484 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004485 " match expected output." )
4486 main.log.debug( self.name + " expected: " + pattern )
4487 main.log.debug( self.name + " actual: " + repr( output ) )
4488 return None
Jon Hall390696c2015-05-05 17:13:41 -07004489 except TypeError:
4490 main.log.exception( self.name + ": Object not as expected" )
4491 return None
Jon Hall390696c2015-05-05 17:13:41 -07004492 except Exception:
4493 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004494 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004495
Jon Hall935db192016-04-19 00:22:04 -07004496 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004497 """
4498 CLI command to get a distributed counter then add a delta to it.
4499 Required arguments:
4500 counter - The name of the counter to increment.
4501 Optional arguments:
4502 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004503 returns:
4504 integer value of the counter or
4505 None on Error
4506 """
4507 try:
4508 counter = str( counter )
4509 delta = int( delta )
4510 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004511 cmdStr += counter
4512 if delta != 1:
4513 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004514 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004515 pattern = counter + " was updated to (-?\d+)"
4516 match = re.search( pattern, output )
4517 if match:
4518 return int( match.group( 1 ) )
4519 else:
4520 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4521 " match expected output." )
4522 main.log.debug( self.name + " expected: " + pattern )
4523 main.log.debug( self.name + " actual: " + repr( output ) )
4524 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004525 except TypeError:
4526 main.log.exception( self.name + ": Object not as expected" )
4527 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004528 except Exception:
4529 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004530 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004531
4532 def valueTestGet( self, valueName ):
4533 """
4534 CLI command to get the value of an atomic value.
4535 Required arguments:
4536 valueName - The name of the value to get.
4537 returns:
4538 string value of the value or
4539 None on Error
4540 """
4541 try:
4542 valueName = str( valueName )
4543 cmdStr = "value-test "
4544 operation = "get"
4545 cmdStr = "value-test {} {}".format( valueName,
4546 operation )
4547 output = self.distPrimitivesSend( cmdStr )
4548 pattern = "(\w+)"
4549 match = re.search( pattern, output )
4550 if match:
4551 return match.group( 1 )
4552 else:
4553 main.log.error( self.name + ": valueTestGet did not" +
4554 " match expected output." )
4555 main.log.debug( self.name + " expected: " + pattern )
4556 main.log.debug( self.name + " actual: " + repr( output ) )
4557 return None
4558 except TypeError:
4559 main.log.exception( self.name + ": Object not as expected" )
4560 return None
4561 except Exception:
4562 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004563 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004564
4565 def valueTestSet( self, valueName, newValue ):
4566 """
4567 CLI command to set the value of an atomic value.
4568 Required arguments:
4569 valueName - The name of the value to set.
4570 newValue - The value to assign to the given value.
4571 returns:
4572 main.TRUE on success or
4573 main.ERROR on Error
4574 """
4575 try:
4576 valueName = str( valueName )
4577 newValue = str( newValue )
4578 operation = "set"
4579 cmdStr = "value-test {} {} {}".format( valueName,
4580 operation,
4581 newValue )
4582 output = self.distPrimitivesSend( cmdStr )
4583 if output is not None:
4584 return main.TRUE
4585 else:
4586 return main.ERROR
4587 except TypeError:
4588 main.log.exception( self.name + ": Object not as expected" )
4589 return main.ERROR
4590 except Exception:
4591 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004592 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004593
4594 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4595 """
4596 CLI command to compareAndSet the value of an atomic value.
4597 Required arguments:
4598 valueName - The name of the value.
4599 oldValue - Compare the current value of the atomic value to this
4600 newValue - If the value equals oldValue, set the value to newValue
4601 returns:
4602 main.TRUE on success or
4603 main.FALSE on failure or
4604 main.ERROR on Error
4605 """
4606 try:
4607 valueName = str( valueName )
4608 oldValue = str( oldValue )
4609 newValue = str( newValue )
4610 operation = "compareAndSet"
4611 cmdStr = "value-test {} {} {} {}".format( valueName,
4612 operation,
4613 oldValue,
4614 newValue )
4615 output = self.distPrimitivesSend( cmdStr )
4616 pattern = "(\w+)"
4617 match = re.search( pattern, output )
4618 if match:
4619 result = match.group( 1 )
4620 if result == "true":
4621 return main.TRUE
4622 elif result == "false":
4623 return main.FALSE
4624 else:
4625 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4626 " match expected output." )
4627 main.log.debug( self.name + " expected: " + pattern )
4628 main.log.debug( self.name + " actual: " + repr( output ) )
4629 return main.ERROR
4630 except TypeError:
4631 main.log.exception( self.name + ": Object not as expected" )
4632 return main.ERROR
4633 except Exception:
4634 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004635 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004636
4637 def valueTestGetAndSet( self, valueName, newValue ):
4638 """
4639 CLI command to getAndSet the value of an atomic value.
4640 Required arguments:
4641 valueName - The name of the value to get.
4642 newValue - The value to assign to the given value
4643 returns:
4644 string value of the value or
4645 None on Error
4646 """
4647 try:
4648 valueName = str( valueName )
4649 cmdStr = "value-test "
4650 operation = "getAndSet"
4651 cmdStr += valueName + " " + operation
4652 cmdStr = "value-test {} {} {}".format( valueName,
4653 operation,
4654 newValue )
4655 output = self.distPrimitivesSend( cmdStr )
4656 pattern = "(\w+)"
4657 match = re.search( pattern, output )
4658 if match:
4659 return match.group( 1 )
4660 else:
4661 main.log.error( self.name + ": valueTestGetAndSet did not" +
4662 " match expected output." )
4663 main.log.debug( self.name + " expected: " + pattern )
4664 main.log.debug( self.name + " actual: " + repr( output ) )
4665 return None
4666 except TypeError:
4667 main.log.exception( self.name + ": Object not as expected" )
4668 return None
4669 except Exception:
4670 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004671 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004672
4673 def valueTestDestroy( self, valueName ):
4674 """
4675 CLI command to destroy an atomic value.
4676 Required arguments:
4677 valueName - The name of the value to destroy.
4678 returns:
4679 main.TRUE on success or
4680 main.ERROR on Error
4681 """
4682 try:
4683 valueName = str( valueName )
4684 cmdStr = "value-test "
4685 operation = "destroy"
4686 cmdStr += valueName + " " + operation
4687 output = self.distPrimitivesSend( cmdStr )
4688 if output is not None:
4689 return main.TRUE
4690 else:
4691 return main.ERROR
4692 except TypeError:
4693 main.log.exception( self.name + ": Object not as expected" )
4694 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004695 except Exception:
4696 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004697 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004698
YPZhangfebf7302016-05-24 16:45:56 -07004699 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004700 """
4701 Description: Execute summary command in onos
4702 Returns: json object ( summary -j ), returns main.FALSE if there is
4703 no output
4704
4705 """
4706 try:
4707 cmdStr = "summary"
4708 if jsonFormat:
4709 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004710 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004711 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004712 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004713 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004714 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004715 if not handle:
4716 main.log.error( self.name + ": There is no output in " +
4717 "summary command" )
4718 return main.FALSE
4719 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004720 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004721 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004722 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004723 except TypeError:
4724 main.log.exception( self.name + ": Object not as expected" )
4725 return None
4726 except pexpect.EOF:
4727 main.log.error( self.name + ": EOF exception found" )
4728 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004729 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004730 except Exception:
4731 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004732 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004733
Jon Hall935db192016-04-19 00:22:04 -07004734 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004735 """
4736 CLI command to get the value of a key in a consistent map using
4737 transactions. This a test function and can only get keys from the
4738 test map hard coded into the cli command
4739 Required arguments:
4740 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004741 returns:
4742 The string value of the key or
4743 None on Error
4744 """
4745 try:
4746 keyName = str( keyName )
4747 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004748 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004749 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004750 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4751 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004752 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004753 return None
4754 else:
4755 match = re.search( pattern, output )
4756 if match:
4757 return match.groupdict()[ 'value' ]
4758 else:
4759 main.log.error( self.name + ": transactionlMapGet did not" +
4760 " match expected output." )
4761 main.log.debug( self.name + " expected: " + pattern )
4762 main.log.debug( self.name + " actual: " + repr( output ) )
4763 return None
4764 except TypeError:
4765 main.log.exception( self.name + ": Object not as expected" )
4766 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004767 except Exception:
4768 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004769 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004770
Jon Hall935db192016-04-19 00:22:04 -07004771 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004772 """
4773 CLI command to put a value into 'numKeys' number of keys in a
4774 consistent map using transactions. This a test function and can only
4775 put into keys named 'Key#' of the test map hard coded into the cli command
4776 Required arguments:
4777 numKeys - Number of keys to add the value to
4778 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004779 returns:
4780 A dictionary whose keys are the name of the keys put into the map
4781 and the values of the keys are dictionaries whose key-values are
4782 'value': value put into map and optionaly
4783 'oldValue': Previous value in the key or
4784 None on Error
4785
4786 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004787 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4788 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004789 """
4790 try:
4791 numKeys = str( numKeys )
4792 value = str( value )
4793 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004794 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004795 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004796 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4797 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4798 results = {}
4799 for line in output.splitlines():
4800 new = re.search( newPattern, line )
4801 updated = re.search( updatedPattern, line )
4802 if new:
4803 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4804 elif updated:
4805 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004806 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004807 else:
4808 main.log.error( self.name + ": transactionlMapGet did not" +
4809 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004810 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4811 newPattern,
4812 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004813 main.log.debug( self.name + " actual: " + repr( output ) )
4814 return results
4815 except TypeError:
4816 main.log.exception( self.name + ": Object not as expected" )
4817 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004818 except Exception:
4819 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004820 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004821
acsmarsdaea66c2015-09-03 11:44:06 -07004822 def maps( self, jsonFormat=True ):
4823 """
4824 Description: Returns result of onos:maps
4825 Optional:
4826 * jsonFormat: enable json formatting of output
4827 """
4828 try:
4829 cmdStr = "maps"
4830 if jsonFormat:
4831 cmdStr += " -j"
4832 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004833 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004834 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004835 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004836 except AssertionError:
4837 main.log.exception( "" )
4838 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004839 except TypeError:
4840 main.log.exception( self.name + ": Object not as expected" )
4841 return None
4842 except pexpect.EOF:
4843 main.log.error( self.name + ": EOF exception found" )
4844 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004845 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004846 except Exception:
4847 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004848 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004849
4850 def getSwController( self, uri, jsonFormat=True ):
4851 """
4852 Descrition: Gets the controller information from the device
4853 """
4854 try:
4855 cmd = "device-controllers "
4856 if jsonFormat:
4857 cmd += "-j "
4858 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004859 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004860 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004861 return response
Jon Hallc6793552016-01-19 14:18:37 -08004862 except AssertionError:
4863 main.log.exception( "" )
4864 return None
GlennRC050596c2015-11-18 17:06:41 -08004865 except TypeError:
4866 main.log.exception( self.name + ": Object not as expected" )
4867 return None
4868 except pexpect.EOF:
4869 main.log.error( self.name + ": EOF exception found" )
4870 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004871 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004872 except Exception:
4873 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004874 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004875
4876 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4877 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004878 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004879
4880 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004881 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08004882 ip - String or List: The ip address of the controller.
4883 This parameter can be formed in a couple of different ways.
4884 VALID:
4885 10.0.0.1 - just the ip address
4886 tcp:10.0.0.1 - the protocol and the ip address
4887 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4888 so that you can add controllers with different
4889 protocols and ports
4890 INVALID:
4891 10.0.0.1:6653 - this is not supported by ONOS
4892
4893 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4894 port - The port number.
4895 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4896
4897 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4898 """
4899 try:
4900 cmd = "device-setcontrollers"
4901
4902 if jsonFormat:
4903 cmd += " -j"
4904 cmd += " " + uri
4905 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004906 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08004907 for item in ip:
4908 if ":" in item:
4909 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004910 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08004911 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004912 elif "." in sitem[ 1 ]:
4913 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08004914 else:
4915 main.log.error( "Malformed entry: " + item )
4916 raise TypeError
4917 else:
4918 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004919 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004920 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004921 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004922 if "Error" in response:
4923 main.log.error( response )
4924 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004925 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004926 except AssertionError:
4927 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004928 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004929 except TypeError:
4930 main.log.exception( self.name + ": Object not as expected" )
4931 return main.FALSE
4932 except pexpect.EOF:
4933 main.log.error( self.name + ": EOF exception found" )
4934 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004935 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004936 except Exception:
4937 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004938 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004939
4940 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004941 '''
GlennRC20fc6522015-12-23 23:26:57 -08004942 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004943 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08004944 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004945 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08004946 Returns:
4947 Returns main.FALSE if an exception is thrown or an error is present
4948 in the response. Otherwise, returns main.TRUE.
4949 NOTE:
4950 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004951 '''
GlennRC20fc6522015-12-23 23:26:57 -08004952 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004953 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07004954 deviceStr = device
4955 device = []
4956 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004957
4958 for d in device:
4959 time.sleep( 1 )
4960 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004961 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004962 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004963 if "Error" in response:
4964 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4965 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004966 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004967 except AssertionError:
4968 main.log.exception( "" )
4969 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004970 except TypeError:
4971 main.log.exception( self.name + ": Object not as expected" )
4972 return main.FALSE
4973 except pexpect.EOF:
4974 main.log.error( self.name + ": EOF exception found" )
4975 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004976 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004977 except Exception:
4978 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004979 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004980
4981 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004982 '''
GlennRC20fc6522015-12-23 23:26:57 -08004983 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004984 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08004985 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004986 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08004987 Returns:
4988 Returns main.FALSE if an exception is thrown or an error is present
4989 in the response. Otherwise, returns main.TRUE.
4990 NOTE:
4991 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004992 '''
GlennRC20fc6522015-12-23 23:26:57 -08004993 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004994 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08004995 host = list( host )
4996
4997 for h in host:
4998 time.sleep( 1 )
4999 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005000 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005001 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005002 if "Error" in response:
5003 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5004 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005005 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005006 except AssertionError:
5007 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005008 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005009 except TypeError:
5010 main.log.exception( self.name + ": Object not as expected" )
5011 return main.FALSE
5012 except pexpect.EOF:
5013 main.log.error( self.name + ": EOF exception found" )
5014 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005015 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005016 except Exception:
5017 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005018 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005019
YPZhangfebf7302016-05-24 16:45:56 -07005020 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005021 '''
GlennRCed771242016-01-13 17:02:47 -08005022 Description:
5023 Bring link down or up in the null-provider.
5024 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005025 begin - (string) One end of a device or switch.
5026 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005027 returns:
5028 main.TRUE if no exceptions were thrown and no Errors are
5029 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005030 '''
GlennRCed771242016-01-13 17:02:47 -08005031 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005032 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005033 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005034 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005035 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005036 if "Error" in response or "Failure" in response:
5037 main.log.error( response )
5038 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005039 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005040 except AssertionError:
5041 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005042 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005043 except TypeError:
5044 main.log.exception( self.name + ": Object not as expected" )
5045 return main.FALSE
5046 except pexpect.EOF:
5047 main.log.error( self.name + ": EOF exception found" )
5048 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005049 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005050 except Exception:
5051 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005052 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005053
Jon Hall2c8959e2016-12-16 12:17:34 -08005054 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005055 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005056 Description:
5057 Changes the state of port in an OF switch by means of the
5058 PORTSTATUS OF messages.
5059 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005060 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5061 port - (string) target port in the device. Ex: '2'
5062 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005063 returns:
5064 main.TRUE if no exceptions were thrown and no Errors are
5065 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005066 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005067 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005068 state = state.lower()
5069 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005070 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005071 response = self.sendline( cmd, showResponse=True )
5072 assert response is not None, "Error in sendline"
5073 assert "Command not found:" not in response, response
5074 if "Error" in response or "Failure" in response:
5075 main.log.error( response )
5076 return main.FALSE
5077 return main.TRUE
5078 except AssertionError:
5079 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005080 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005081 except TypeError:
5082 main.log.exception( self.name + ": Object not as expected" )
5083 return main.FALSE
5084 except pexpect.EOF:
5085 main.log.error( self.name + ": EOF exception found" )
5086 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005087 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005088 except Exception:
5089 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005090 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005091
5092 def logSet( self, level="INFO", app="org.onosproject" ):
5093 """
5094 Set the logging level to lvl for a specific app
5095 returns main.TRUE on success
5096 returns main.FALSE if Error occurred
5097 if noExit is True, TestON will not exit, but clean up
5098 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5099 Level defaults to INFO
5100 """
5101 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005102 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005103 self.handle.expect( "onos>" )
5104
5105 response = self.handle.before
5106 if re.search( "Error", response ):
5107 return main.FALSE
5108 return main.TRUE
5109 except pexpect.TIMEOUT:
5110 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005111 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005112 except pexpect.EOF:
5113 main.log.error( self.name + ": EOF exception found" )
5114 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005115 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005116 except Exception:
5117 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005118 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005119
5120 def getGraphDict( self, timeout=60, includeHost=False ):
5121 """
5122 Return a dictionary which describes the latest network topology data as a
5123 graph.
5124 An example of the dictionary:
5125 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5126 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5127 Each vertex should at least have an 'edges' attribute which describes the
5128 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005129 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005130 list of attributes.
5131 An example of the edges dictionary:
5132 'edges': { vertex2: { 'port': ..., 'weight': ... },
5133 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005134 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005135 in topology data.
5136 """
5137 graphDict = {}
5138 try:
5139 links = self.links()
5140 links = json.loads( links )
5141 devices = self.devices()
5142 devices = json.loads( devices )
5143 idToDevice = {}
5144 for device in devices:
5145 idToDevice[ device[ 'id' ] ] = device
5146 if includeHost:
5147 hosts = self.hosts()
5148 # FIXME: support 'includeHost' argument
5149 for link in links:
5150 nodeA = link[ 'src' ][ 'device' ]
5151 nodeB = link[ 'dst' ][ 'device' ]
5152 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005153 if nodeA not in graphDict.keys():
5154 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005155 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005156 'type': idToDevice[ nodeA ][ 'type' ],
5157 'available': idToDevice[ nodeA ][ 'available' ],
5158 'role': idToDevice[ nodeA ][ 'role' ],
5159 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5160 'hw': idToDevice[ nodeA ][ 'hw' ],
5161 'sw': idToDevice[ nodeA ][ 'sw' ],
5162 'serial': idToDevice[ nodeA ][ 'serial' ],
5163 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005164 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005165 else:
5166 # Assert nodeB is not connected to any current links of nodeA
5167 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005168 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5169 'type': link[ 'type' ],
5170 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005171 return graphDict
5172 except ( TypeError, ValueError ):
5173 main.log.exception( self.name + ": Object not as expected" )
5174 return None
5175 except KeyError:
5176 main.log.exception( self.name + ": KeyError exception found" )
5177 return None
5178 except AssertionError:
5179 main.log.exception( self.name + ": AssertionError exception found" )
5180 return None
5181 except pexpect.EOF:
5182 main.log.error( self.name + ": EOF exception found" )
5183 main.log.error( self.name + ": " + self.handle.before )
5184 return None
5185 except Exception:
5186 main.log.exception( self.name + ": Uncaught exception!" )
5187 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005188
5189 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005190 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005191 Send command to check intent-perf summary
5192 Returns: dictionary for intent-perf summary
5193 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005194 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005195 cmd = "intent-perf -s"
5196 respDic = {}
5197 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005198 assert resp is not None, "Error in sendline"
5199 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005200 try:
5201 # Generate the dictionary to return
5202 for l in resp.split( "\n" ):
5203 # Delete any white space in line
5204 temp = re.sub( r'\s+', '', l )
5205 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005206 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005207
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005208 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005209 main.log.exception( self.name + ": Object not as expected" )
5210 return None
5211 except KeyError:
5212 main.log.exception( self.name + ": KeyError exception found" )
5213 return None
5214 except AssertionError:
5215 main.log.exception( self.name + ": AssertionError exception found" )
5216 return None
5217 except pexpect.EOF:
5218 main.log.error( self.name + ": EOF exception found" )
5219 main.log.error( self.name + ": " + self.handle.before )
5220 return None
5221 except Exception:
5222 main.log.exception( self.name + ": Uncaught exception!" )
5223 return None
5224 return respDic
5225
Chiyu Chengec63bde2016-11-17 18:11:36 -08005226 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005227 """
5228 Searches the latest ONOS log file for the given search term and
5229 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005230
chengchiyu08303a02016-09-08 17:40:26 -07005231 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005232 searchTerm:
5233 The string to grep from the ONOS log.
5234 startLine:
5235 The term that decides which line is the start to search the searchTerm in
5236 the karaf log. For now, startTerm only works in 'first' mode.
5237 logNum:
5238 In some extreme cases, one karaf log is not big enough to contain all the
5239 information.Because of this, search mutiply logs is necessary to capture
5240 the right result. logNum is the number of karaf logs that we need to search
5241 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005242 mode:
5243 all: return all the strings that contain the search term
5244 last: return the last string that contains the search term
5245 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005246 num: return the number of times that the searchTerm appears in the log
5247 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005248 """
5249 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005250 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005251 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005252 logPath = '/opt/onos/log/karaf.log.'
5253 logPaths = '/opt/onos/log/karaf.log'
5254 for i in range( 1, logNum ):
5255 logPaths = logPath + str( i ) + " " + logPaths
5256 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005257 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005258 # 100000000 is just a extreme large number to make sure this function can
5259 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005260 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005261 if mode == 'all':
5262 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005263 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005264 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005265 elif mode == 'first':
5266 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5267 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005268 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005269 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005270 return num
You Wang6d301d42017-04-21 10:49:33 -07005271 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005272 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005273 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005274 else:
5275 main.log.error( self.name + " unsupported mode" )
5276 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005277 before = self.sendline( cmd )
5278 before = before.splitlines()
5279 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005280 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005281 return returnLines
5282 except AssertionError:
5283 main.log.error( self.name + " searchTerm is not string type" )
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 )
Devin Lim44075962017-08-11 10:56:37 -07005288 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005289 except pexpect.TIMEOUT:
5290 main.log.error( self.name + ": TIMEOUT exception found" )
5291 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005292 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005293 except Exception:
5294 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005295 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005296
5297 def vplsShow( self, jsonFormat=True ):
5298 """
5299 Description: Returns result of onos:vpls show, which should list the
5300 configured VPLS networks and the assigned interfaces.
5301 Optional:
5302 * jsonFormat: enable json formatting of output
5303 Returns:
5304 The output of the command or None on error.
5305 """
5306 try:
5307 cmdStr = "vpls show"
5308 if jsonFormat:
5309 raise NotImplementedError
5310 cmdStr += " -j"
5311 handle = self.sendline( cmdStr )
5312 assert handle is not None, "Error in sendline"
5313 assert "Command not found:" not in handle, handle
5314 return handle
5315 except AssertionError:
5316 main.log.exception( "" )
5317 return None
5318 except TypeError:
5319 main.log.exception( self.name + ": Object not as expected" )
5320 return None
5321 except pexpect.EOF:
5322 main.log.error( self.name + ": EOF exception found" )
5323 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005324 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005325 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005326 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005327 return None
5328 except Exception:
5329 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005330 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005331
5332 def parseVplsShow( self ):
5333 """
5334 Parse the cli output of 'vpls show' into json output. This is required
5335 as there is currently no json output available.
5336 """
5337 try:
5338 output = []
5339 raw = self.vplsShow( jsonFormat=False )
5340 namePat = "VPLS name: (?P<name>\w+)"
5341 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5342 encapPat = "Encapsulation: (?P<encap>\w+)"
5343 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5344 mIter = re.finditer( pattern, raw )
5345 for match in mIter:
5346 item = {}
5347 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005348 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005349 if ifaces == [ "" ]:
5350 ifaces = []
5351 item[ 'interfaces' ] = ifaces
5352 encap = match.group( 'encap' )
5353 if encap != 'NONE':
5354 item[ 'encapsulation' ] = encap.lower()
5355 output.append( item )
5356 return output
5357 except Exception:
5358 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005359 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005360
5361 def vplsList( self, jsonFormat=True ):
5362 """
5363 Description: Returns result of onos:vpls list, which should list the
5364 configured VPLS networks.
5365 Optional:
5366 * jsonFormat: enable json formatting of output
5367 """
5368 try:
5369 cmdStr = "vpls list"
5370 if jsonFormat:
5371 raise NotImplementedError
5372 cmdStr += " -j"
5373 handle = self.sendline( cmdStr )
5374 assert handle is not None, "Error in sendline"
5375 assert "Command not found:" not in handle, handle
5376 return handle
5377 except AssertionError:
5378 main.log.exception( "" )
5379 return None
5380 except TypeError:
5381 main.log.exception( self.name + ": Object not as expected" )
5382 return None
5383 except pexpect.EOF:
5384 main.log.error( self.name + ": EOF exception found" )
5385 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005386 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005387 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005388 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005389 return None
5390 except Exception:
5391 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005392 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005393
5394 def vplsCreate( self, network ):
5395 """
5396 CLI command to create a new VPLS network.
5397 Required arguments:
5398 network - String name of the network to create.
5399 returns:
5400 main.TRUE on success and main.FALSE on failure
5401 """
5402 try:
5403 network = str( network )
5404 cmdStr = "vpls create "
5405 cmdStr += network
5406 output = self.sendline( cmdStr )
5407 assert output is not None, "Error in sendline"
5408 assert "Command not found:" not in output, output
5409 assert "Error executing command" not in output, output
5410 assert "VPLS already exists:" not in output, output
5411 return main.TRUE
5412 except AssertionError:
5413 main.log.exception( "" )
5414 return main.FALSE
5415 except TypeError:
5416 main.log.exception( self.name + ": Object not as expected" )
5417 return main.FALSE
5418 except pexpect.EOF:
5419 main.log.error( self.name + ": EOF exception found" )
5420 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005421 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005422 except Exception:
5423 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005424 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005425
5426 def vplsDelete( self, network ):
5427 """
5428 CLI command to delete a VPLS network.
5429 Required arguments:
5430 network - Name of the network to delete.
5431 returns:
5432 main.TRUE on success and main.FALSE on failure
5433 """
5434 try:
5435 network = str( network )
5436 cmdStr = "vpls delete "
5437 cmdStr += network
5438 output = self.sendline( cmdStr )
5439 assert output is not None, "Error in sendline"
5440 assert "Command not found:" not in output, output
5441 assert "Error executing command" not in output, output
5442 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005443 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005444 return main.TRUE
5445 except AssertionError:
5446 main.log.exception( "" )
5447 return main.FALSE
5448 except TypeError:
5449 main.log.exception( self.name + ": Object not as expected" )
5450 return main.FALSE
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 Exception:
5456 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005457 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005458
5459 def vplsAddIface( self, network, iface ):
5460 """
5461 CLI command to add an interface to a VPLS network.
5462 Required arguments:
5463 network - Name of the network to add the interface to.
5464 iface - The ONOS name for an interface.
5465 returns:
5466 main.TRUE on success and main.FALSE on failure
5467 """
5468 try:
5469 network = str( network )
5470 iface = str( iface )
5471 cmdStr = "vpls add-if "
5472 cmdStr += network + " " + iface
5473 output = self.sendline( cmdStr )
5474 assert output is not None, "Error in sendline"
5475 assert "Command not found:" not in output, output
5476 assert "Error executing command" not in output, output
5477 assert "already associated to network" not in output, output
5478 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005479 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005480 return main.TRUE
5481 except AssertionError:
5482 main.log.exception( "" )
5483 return main.FALSE
5484 except TypeError:
5485 main.log.exception( self.name + ": Object not as expected" )
5486 return main.FALSE
5487 except pexpect.EOF:
5488 main.log.error( self.name + ": EOF exception found" )
5489 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005490 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005491 except Exception:
5492 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005493 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005494
5495 def vplsRemIface( self, network, iface ):
5496 """
5497 CLI command to remove an interface from a VPLS network.
5498 Required arguments:
5499 network - Name of the network to remove the interface from.
5500 iface - Name of the interface to remove.
5501 returns:
5502 main.TRUE on success and main.FALSE on failure
5503 """
5504 try:
5505 iface = str( iface )
5506 cmdStr = "vpls rem-if "
5507 cmdStr += network + " " + iface
5508 output = self.sendline( cmdStr )
5509 assert output is not None, "Error in sendline"
5510 assert "Command not found:" not in output, output
5511 assert "Error executing command" not in output, output
5512 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005513 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005514 return main.TRUE
5515 except AssertionError:
5516 main.log.exception( "" )
5517 return main.FALSE
5518 except TypeError:
5519 main.log.exception( self.name + ": Object not as expected" )
5520 return main.FALSE
5521 except pexpect.EOF:
5522 main.log.error( self.name + ": EOF exception found" )
5523 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005524 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005525 except Exception:
5526 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005527 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005528
5529 def vplsClean( self ):
5530 """
5531 Description: Clears the VPLS app configuration.
5532 Returns: main.TRUE on success and main.FALSE on failure
5533 """
5534 try:
5535 cmdStr = "vpls clean"
5536 handle = self.sendline( cmdStr )
5537 assert handle is not None, "Error in sendline"
5538 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005539 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005540 return handle
5541 except AssertionError:
5542 main.log.exception( "" )
5543 return main.FALSE
5544 except TypeError:
5545 main.log.exception( self.name + ": Object not as expected" )
5546 return main.FALSE
5547 except pexpect.EOF:
5548 main.log.error( self.name + ": EOF exception found" )
5549 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005550 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005551 except Exception:
5552 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005553 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005554
5555 def vplsSetEncap( self, network, encapType ):
5556 """
5557 CLI command to add an interface to a VPLS network.
5558 Required arguments:
5559 network - Name of the network to create.
5560 encapType - Type of encapsulation.
5561 returns:
5562 main.TRUE on success and main.FALSE on failure
5563 """
5564 try:
5565 network = str( network )
5566 encapType = str( encapType ).upper()
5567 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5568 cmdStr = "vpls set-encap "
5569 cmdStr += network + " " + encapType
5570 output = self.sendline( cmdStr )
5571 assert output is not None, "Error in sendline"
5572 assert "Command not found:" not in output, output
5573 assert "Error executing command" not in output, output
5574 assert "already associated to network" not in output, output
5575 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005576 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005577 return main.TRUE
5578 except AssertionError:
5579 main.log.exception( "" )
5580 return main.FALSE
5581 except TypeError:
5582 main.log.exception( self.name + ": Object not as expected" )
5583 return main.FALSE
5584 except pexpect.EOF:
5585 main.log.error( self.name + ": EOF exception found" )
5586 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005587 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005588 except Exception:
5589 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005590 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005591
5592 def interfaces( self, jsonFormat=True ):
5593 """
5594 Description: Returns result of interfaces command.
5595 Optional:
5596 * jsonFormat: enable json formatting of output
5597 Returns:
5598 The output of the command or None on error.
5599 """
5600 try:
5601 cmdStr = "interfaces"
5602 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005603 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005604 cmdStr += " -j"
5605 handle = self.sendline( cmdStr )
5606 assert handle is not None, "Error in sendline"
5607 assert "Command not found:" not in handle, handle
5608 return handle
5609 except AssertionError:
5610 main.log.exception( "" )
5611 return None
5612 except TypeError:
5613 main.log.exception( self.name + ": Object not as expected" )
5614 return None
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 NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005620 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005621 return None
5622 except Exception:
5623 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005624 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005625
5626 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005627 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005628 Get the timestamp of searchTerm from karaf log.
5629
5630 Arguments:
5631 splitTerm_before and splitTerm_after:
5632
5633 The terms that split the string that contains the timeStamp of
5634 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5635 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5636 and the splitTerm_after is "x"
5637
5638 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005639 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005640 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005641 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005642 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005643 return main.ERROR
5644 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005645 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005646 main.log.warn( "Captured timestamp string is empty" )
5647 return main.ERROR
5648 lines = lines[ 0 ]
5649 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005650 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005651 # get the target value
5652 line = lines.split( splitTerm_before )
5653 key = line[ 1 ].split( splitTerm_after )
5654 return int( key[ 0 ] )
5655 except IndexError:
5656 main.log.warn( "Index Error!" )
5657 return main.ERROR
5658 except AssertionError:
5659 main.log.warn( "Search Term Not Found " )
5660 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005661
5662 def workQueueAdd( self, queueName, value ):
5663 """
5664 CLI command to add a string to the specified Work Queue.
5665 This function uses the distributed primitives test app, which
5666 gives some cli access to distributed primitives for testing
5667 purposes only.
5668
5669 Required arguments:
5670 queueName - The name of the queue to add to
5671 value - The value to add to the queue
5672 returns:
5673 main.TRUE on success, main.FALSE on failure and
5674 main.ERROR on error.
5675 """
5676 try:
5677 queueName = str( queueName )
5678 value = str( value )
5679 prefix = "work-queue-test"
5680 operation = "add"
5681 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5682 output = self.distPrimitivesSend( cmdStr )
5683 if "Invalid operation name" in output:
5684 main.log.warn( output )
5685 return main.ERROR
5686 elif "Done" in output:
5687 return main.TRUE
5688 except TypeError:
5689 main.log.exception( self.name + ": Object not as expected" )
5690 return main.ERROR
5691 except Exception:
5692 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005693 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005694
5695 def workQueueAddMultiple( self, queueName, value1, value2 ):
5696 """
5697 CLI command to add two strings to the specified Work Queue.
5698 This function uses the distributed primitives test app, which
5699 gives some cli access to distributed primitives for testing
5700 purposes only.
5701
5702 Required arguments:
5703 queueName - The name of the queue to add to
5704 value1 - The first value to add to the queue
5705 value2 - The second value to add to the queue
5706 returns:
5707 main.TRUE on success, main.FALSE on failure and
5708 main.ERROR on error.
5709 """
5710 try:
5711 queueName = str( queueName )
5712 value1 = str( value1 )
5713 value2 = str( value2 )
5714 prefix = "work-queue-test"
5715 operation = "addMultiple"
5716 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5717 output = self.distPrimitivesSend( cmdStr )
5718 if "Invalid operation name" in output:
5719 main.log.warn( output )
5720 return main.ERROR
5721 elif "Done" in output:
5722 return main.TRUE
5723 except TypeError:
5724 main.log.exception( self.name + ": Object not as expected" )
5725 return main.ERROR
5726 except Exception:
5727 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005728 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005729
5730 def workQueueTakeAndComplete( self, queueName, number=1 ):
5731 """
5732 CLI command to take a value from the specified Work Queue and compelte it.
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 number - The number of items to take and complete
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 number = str( int( number ) )
5747 prefix = "work-queue-test"
5748 operation = "takeAndComplete"
5749 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
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 workQueueDestroy( self, queueName ):
5764 """
5765 CLI command to destroy 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 returns:
5773 main.TRUE on success, main.FALSE on failure and
5774 main.ERROR on error.
5775 """
5776 try:
5777 queueName = str( queueName )
5778 prefix = "work-queue-test"
5779 operation = "destroy"
5780 cmdStr = " ".join( [ prefix, queueName, operation ] )
5781 output = self.distPrimitivesSend( cmdStr )
5782 if "Invalid operation name" in output:
5783 main.log.warn( output )
5784 return main.ERROR
5785 return main.TRUE
5786 except TypeError:
5787 main.log.exception( self.name + ": Object not as expected" )
5788 return main.ERROR
5789 except Exception:
5790 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005791 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005792
5793 def workQueueTotalPending( self, queueName ):
5794 """
5795 CLI command to get the Total Pending items of the specified Work Queue.
5796 This function uses the distributed primitives test app, which
5797 gives some cli access to distributed primitives for testing
5798 purposes only.
5799
5800 Required arguments:
5801 queueName - The name of the queue to add to
5802 returns:
5803 The number of Pending items in the specified work queue or
5804 None on error
5805 """
5806 try:
5807 queueName = str( queueName )
5808 prefix = "work-queue-test"
5809 operation = "totalPending"
5810 cmdStr = " ".join( [ prefix, queueName, operation ] )
5811 output = self.distPrimitivesSend( cmdStr )
5812 pattern = r'\d+'
5813 if "Invalid operation name" in output:
5814 main.log.warn( output )
5815 return None
5816 else:
5817 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005818 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005819 except ( AttributeError, TypeError ):
5820 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5821 return None
5822 except Exception:
5823 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005824 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005825
5826 def workQueueTotalCompleted( self, queueName ):
5827 """
5828 CLI command to get the Total Completed items of the specified Work Queue.
5829 This function uses the distributed primitives test app, which
5830 gives some cli access to distributed primitives for testing
5831 purposes only.
5832
5833 Required arguments:
5834 queueName - The name of the queue to add to
5835 returns:
5836 The number of complete items in the specified work queue or
5837 None on error
5838 """
5839 try:
5840 queueName = str( queueName )
5841 prefix = "work-queue-test"
5842 operation = "totalCompleted"
5843 cmdStr = " ".join( [ prefix, queueName, operation ] )
5844 output = self.distPrimitivesSend( cmdStr )
5845 pattern = r'\d+'
5846 if "Invalid operation name" in output:
5847 main.log.warn( output )
5848 return None
5849 else:
5850 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005851 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005852 except ( AttributeError, TypeError ):
5853 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5854 return None
5855 except Exception:
5856 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005857 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005858
5859 def workQueueTotalInProgress( self, queueName ):
5860 """
5861 CLI command to get the Total In Progress items of the specified Work Queue.
5862 This function uses the distributed primitives test app, which
5863 gives some cli access to distributed primitives for testing
5864 purposes only.
5865
5866 Required arguments:
5867 queueName - The name of the queue to add to
5868 returns:
5869 The number of In Progress items in the specified work queue or
5870 None on error
5871 """
5872 try:
5873 queueName = str( queueName )
5874 prefix = "work-queue-test"
5875 operation = "totalInProgress"
5876 cmdStr = " ".join( [ prefix, queueName, operation ] )
5877 output = self.distPrimitivesSend( cmdStr )
5878 pattern = r'\d+'
5879 if "Invalid operation name" in output:
5880 main.log.warn( output )
5881 return None
5882 else:
5883 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005884 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005885 except ( AttributeError, TypeError ):
5886 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5887 return None
5888 except Exception:
5889 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005890 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005891
5892 def events( self, args='-a' ):
5893 """
5894 Description: Returns events -a command output
5895 Optional:
5896 add other arguments
5897 """
5898 try:
5899 cmdStr = "events"
5900 if args:
5901 cmdStr += " " + args
5902 handle = self.sendline( cmdStr )
5903 assert handle is not None, "Error in sendline"
5904 assert "Command not found:" not in handle, handle
5905 return handle
5906 except AssertionError:
5907 main.log.exception( "" )
5908 return None
5909 except TypeError:
5910 main.log.exception( self.name + ": Object not as expected" )
5911 return None
5912 except pexpect.EOF:
5913 main.log.error( self.name + ": EOF exception found" )
5914 main.log.error( self.name + ": " + self.handle.before )
5915 main.cleanAndExit()
5916 except Exception:
5917 main.log.exception( self.name + ": Uncaught exception!" )
5918 main.cleanAndExit()
5919
5920 def getMaster( self, deviceID ):
5921 """
5922 Description: Obtains current master using "roles" command for a specific deviceID
5923 """
5924 try:
5925 return str( self.getRole( deviceID )[ 'master' ] )
5926 except AssertionError:
5927 main.log.exception( "" )
5928 return None
5929 except TypeError:
5930 main.log.exception( self.name + ": Object not as expected" )
5931 return None
5932 except pexpect.EOF:
5933 main.log.error( self.name + ": EOF exception found" )
5934 main.log.error( self.name + ": " + self.handle.before )
5935 main.cleanAndExit()
5936 except Exception:
5937 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07005938 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08005939
5940 def issu( self ):
5941 """
5942 Short summary of In-Service Software Upgrade status
5943
5944 Returns the output of the cli command or None on Error
5945 """
5946 try:
5947 cmdStr = "issu"
5948 handle = self.sendline( cmdStr )
5949 assert handle is not None, "Error in sendline"
5950 assert "Command not found:" not in handle, handle
5951 assert "Unsupported command:" not in handle, handle
5952 return handle
5953 except AssertionError:
5954 main.log.exception( "" )
5955 return None
5956 except TypeError:
5957 main.log.exception( self.name + ": Object not as expected" )
5958 return None
5959 except pexpect.EOF:
5960 main.log.error( self.name + ": EOF exception found" )
5961 main.log.error( self.name + ": " + self.handle.before )
5962 main.cleanAndExit()
5963 except Exception:
5964 main.log.exception( self.name + ": Uncaught exception!" )
5965 main.cleanAndExit()
5966
5967 def issuInit( self ):
5968 """
5969 Initiates an In-Service Software Upgrade
5970
5971 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5972 """
5973 try:
5974 cmdStr = "issu init"
5975 handle = self.sendline( cmdStr )
5976 assert handle is not None, "Error in sendline"
5977 assert "Command not found:" not in handle, handle
5978 assert "Unsupported command:" not in handle, handle
5979 if "Initialized" in handle:
5980 return main.TRUE
5981 else:
5982 return main.FALSE
5983 except AssertionError:
5984 main.log.exception( "" )
5985 return main.ERROR
5986 except TypeError:
5987 main.log.exception( self.name + ": Object not as expected" )
5988 return main.ERROR
5989 except pexpect.EOF:
5990 main.log.error( self.name + ": EOF exception found" )
5991 main.log.error( self.name + ": " + self.handle.before )
5992 main.cleanAndExit()
5993 except Exception:
5994 main.log.exception( self.name + ": Uncaught exception!" )
5995 main.cleanAndExit()
5996
5997 def issuUpgrade( self ):
5998 """
5999 Transitions stores to upgraded nodes
6000
6001 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6002 """
6003 try:
6004 cmdStr = "issu upgrade"
6005 handle = self.sendline( cmdStr )
6006 assert handle is not None, "Error in sendline"
6007 assert "Command not found:" not in handle, handle
6008 assert "Unsupported command:" not in handle, handle
6009 if "Upgraded" in handle:
6010 return main.TRUE
6011 else:
6012 return main.FALSE
6013 except AssertionError:
6014 main.log.exception( "" )
6015 return main.ERROR
6016 except TypeError:
6017 main.log.exception( self.name + ": Object not as expected" )
6018 return main.ERROR
6019 except pexpect.EOF:
6020 main.log.error( self.name + ": EOF exception found" )
6021 main.log.error( self.name + ": " + self.handle.before )
6022 main.cleanAndExit()
6023 except Exception:
6024 main.log.exception( self.name + ": Uncaught exception!" )
6025 main.cleanAndExit()
6026
6027 def issuCommit( self ):
6028 """
6029 Finalizes an In-Service Software Upgrade
6030
6031 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6032 """
6033 try:
6034 cmdStr = "issu commit"
6035 handle = self.sendline( cmdStr )
6036 assert handle is not None, "Error in sendline"
6037 assert "Command not found:" not in handle, handle
6038 assert "Unsupported command:" not in handle, handle
6039 # TODO: Check the version returned by this command
6040 if "Committed version" in handle:
6041 return main.TRUE
6042 else:
6043 return main.FALSE
6044 except AssertionError:
6045 main.log.exception( "" )
6046 return main.ERROR
6047 except TypeError:
6048 main.log.exception( self.name + ": Object not as expected" )
6049 return main.ERROR
6050 except pexpect.EOF:
6051 main.log.error( self.name + ": EOF exception found" )
6052 main.log.error( self.name + ": " + self.handle.before )
6053 main.cleanAndExit()
6054 except Exception:
6055 main.log.exception( self.name + ": Uncaught exception!" )
6056 main.cleanAndExit()
6057
6058 def issuRollback( self ):
6059 """
6060 Rolls back an In-Service Software Upgrade
6061
6062 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6063 """
6064 try:
6065 cmdStr = "issu rollback"
6066 handle = self.sendline( cmdStr )
6067 assert handle is not None, "Error in sendline"
6068 assert "Command not found:" not in handle, handle
6069 assert "Unsupported command:" not in handle, handle
6070 # TODO: Check the version returned by this command
6071 if "Rolled back to version" in handle:
6072 return main.TRUE
6073 else:
6074 return main.FALSE
6075 except AssertionError:
6076 main.log.exception( "" )
6077 return main.ERROR
6078 except TypeError:
6079 main.log.exception( self.name + ": Object not as expected" )
6080 return main.ERROR
6081 except pexpect.EOF:
6082 main.log.error( self.name + ": EOF exception found" )
6083 main.log.error( self.name + ": " + self.handle.before )
6084 main.cleanAndExit()
6085 except Exception:
6086 main.log.exception( self.name + ": Uncaught exception!" )
6087 main.cleanAndExit()
6088
6089 def issuReset( self ):
6090 """
6091 Resets the In-Service Software Upgrade status after a rollback
6092
6093 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6094 """
6095 try:
6096 cmdStr = "issu reset"
6097 handle = self.sendline( cmdStr )
6098 assert handle is not None, "Error in sendline"
6099 assert "Command not found:" not in handle, handle
6100 assert "Unsupported command:" not in handle, handle
6101 # TODO: Check the version returned by this command
6102 if "Reset version" in handle:
6103 return main.TRUE
6104 else:
6105 return main.FALSE
6106 except AssertionError:
6107 main.log.exception( "" )
6108 return main.ERROR
6109 except TypeError:
6110 main.log.exception( self.name + ": Object not as expected" )
6111 return main.ERROR
6112 except pexpect.EOF:
6113 main.log.error( self.name + ": EOF exception found" )
6114 main.log.error( self.name + ": " + self.handle.before )
6115 main.cleanAndExit()
6116 except Exception:
6117 main.log.exception( self.name + ": Uncaught exception!" )
6118 main.cleanAndExit()
6119
6120 def issuStatus( self ):
6121 """
6122 Status of an In-Service Software Upgrade
6123
6124 Returns the output of the cli command or None on Error
6125 """
6126 try:
6127 cmdStr = "issu status"
6128 handle = self.sendline( cmdStr )
6129 assert handle is not None, "Error in sendline"
6130 assert "Command not found:" not in handle, handle
6131 assert "Unsupported command:" not in handle, handle
6132 return handle
6133 except AssertionError:
6134 main.log.exception( "" )
6135 return None
6136 except TypeError:
6137 main.log.exception( self.name + ": Object not as expected" )
6138 return None
6139 except pexpect.EOF:
6140 main.log.error( self.name + ": EOF exception found" )
6141 main.log.error( self.name + ": " + self.handle.before )
6142 main.cleanAndExit()
6143 except Exception:
6144 main.log.exception( self.name + ": Uncaught exception!" )
6145 main.cleanAndExit()
6146
6147 def issuVersion( self ):
6148 """
6149 Get the version of an In-Service Software Upgrade
6150
6151 Returns the output of the cli command or None on Error
6152 """
6153 try:
6154 cmdStr = "issu version"
6155 handle = self.sendline( cmdStr )
6156 assert handle is not None, "Error in sendline"
6157 assert "Command not found:" not in handle, handle
6158 assert "Unsupported command:" not in handle, handle
6159 return handle
6160 except AssertionError:
6161 main.log.exception( "" )
6162 return None
6163 except TypeError:
6164 main.log.exception( self.name + ": Object not as expected" )
6165 return None
6166 except pexpect.EOF:
6167 main.log.error( self.name + ": EOF exception found" )
6168 main.log.error( self.name + ": " + self.handle.before )
6169 main.cleanAndExit()
6170 except Exception:
6171 main.log.exception( self.name + ": Uncaught exception!" )
6172 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006173
6174 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6175 """
6176 Create a multicast route by calling 'mcast-join' command
6177 sIP: source IP of the multicast route
6178 groupIP: group IP of the multicast route
6179 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6180 dPorts: a list of destination ports of the multicast route
6181 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6182 """
6183 try:
6184 cmdStr = "mcast-join"
6185 cmdStr += " " + str( sIP )
6186 cmdStr += " " + str( groupIP )
6187 cmdStr += " " + str( sPort )
6188 assert isinstance( dPorts, list )
6189 for dPort in dPorts:
6190 cmdStr += " " + str( dPort )
6191 handle = self.sendline( cmdStr )
6192 assert handle is not None, "Error in sendline"
6193 assert "Command not found:" not in handle, handle
6194 assert "Unsupported command:" not in handle, handle
6195 assert "Error executing command" not in handle, handle
6196 if "Added the mcast route" in handle:
6197 return main.TRUE
6198 else:
6199 return main.FALSE
6200 except AssertionError:
6201 main.log.exception( "" )
6202 return None
6203 except TypeError:
6204 main.log.exception( self.name + ": Object not as expected" )
6205 return None
6206 except pexpect.EOF:
6207 main.log.error( self.name + ": EOF exception found" )
6208 main.log.error( self.name + ": " + self.handle.before )
6209 main.cleanAndExit()
6210 except Exception:
6211 main.log.exception( self.name + ": Uncaught exception!" )
6212 main.cleanAndExit()
6213
6214 def mcastDelete( self, sIP, groupIP, dPorts ):
6215 """
6216 Delete a multicast route by calling 'mcast-delete' command
6217 sIP: source IP of the multicast route
6218 groupIP: group IP of the multicast route
6219 dPorts: a list of destination ports of the multicast route
6220 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6221 """
6222 try:
6223 cmdStr = "mcast-delete"
6224 cmdStr += " " + str( sIP )
6225 cmdStr += " " + str( groupIP )
6226 assert isinstance( dPorts, list )
6227 for dPort in dPorts:
6228 cmdStr += " " + str( dPort )
6229 handle = self.sendline( cmdStr )
6230 assert handle is not None, "Error in sendline"
6231 assert "Command not found:" not in handle, handle
6232 assert "Unsupported command:" not in handle, handle
6233 assert "Error executing command" not in handle, handle
6234 if "Updated the mcast route" in handle:
6235 return main.TRUE
6236 else:
6237 return main.FALSE
6238 except AssertionError:
6239 main.log.exception( "" )
6240 return None
6241 except TypeError:
6242 main.log.exception( self.name + ": Object not as expected" )
6243 return None
6244 except pexpect.EOF:
6245 main.log.error( self.name + ": EOF exception found" )
6246 main.log.error( self.name + ": " + self.handle.before )
6247 main.cleanAndExit()
6248 except Exception:
6249 main.log.exception( self.name + ": Uncaught exception!" )
6250 main.cleanAndExit()
6251
6252 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6253 """
6254 Create a multicast route by calling 'mcast-host-join' command
6255 sAddr: we can provide * for ASM or a specific address for SSM
6256 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006257 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006258 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6259 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6260 """
6261 try:
6262 cmdStr = "mcast-host-join"
6263 cmdStr += " -sAddr " + str( sAddr )
6264 cmdStr += " -gAddr " + str( gAddr )
6265 assert isinstance( srcs, list )
6266 for src in srcs:
6267 cmdStr += " -srcs " + str( src )
6268 assert isinstance( sinks, list )
6269 for sink in sinks:
6270 cmdStr += " -sinks " + str( sink )
6271 handle = self.sendline( cmdStr )
6272 assert handle is not None, "Error in sendline"
6273 assert "Command not found:" not in handle, handle
6274 assert "Unsupported command:" not in handle, handle
6275 assert "Error executing command" not in handle, handle
6276 if "Added the mcast route" in handle:
6277 return main.TRUE
6278 else:
6279 return main.FALSE
6280 except AssertionError:
6281 main.log.exception( "" )
6282 return None
6283 except TypeError:
6284 main.log.exception( self.name + ": Object not as expected" )
6285 return None
6286 except pexpect.EOF:
6287 main.log.error( self.name + ": EOF exception found" )
6288 main.log.error( self.name + ": " + self.handle.before )
6289 main.cleanAndExit()
6290 except Exception:
6291 main.log.exception( self.name + ": Uncaught exception!" )
6292 main.cleanAndExit()
6293
6294 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6295 """
6296 Delete multicast sink(s) by calling 'mcast-host-delete' command
6297 sAddr: we can provide * for ASM or a specific address for SSM
6298 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006299 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006300 will delete the route if not specified
6301 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6302 """
6303 try:
6304 cmdStr = "mcast-host-delete"
6305 cmdStr += " -sAddr " + str( sAddr )
6306 cmdStr += " -gAddr " + str( gAddr )
6307 if host:
6308 cmdStr += " -h " + str( host )
6309 handle = self.sendline( cmdStr )
6310 assert handle is not None, "Error in sendline"
6311 assert "Command not found:" not in handle, handle
6312 assert "Unsupported command:" not in handle, handle
6313 assert "Error executing command" not in handle, handle
6314 if "Updated the mcast route" in handle:
6315 return main.TRUE
6316 elif "Deleted the mcast route" in handle:
6317 return main.TRUE
6318 else:
6319 return main.FALSE
6320 except AssertionError:
6321 main.log.exception( "" )
6322 return None
6323 except TypeError:
6324 main.log.exception( self.name + ": Object not as expected" )
6325 return None
6326 except pexpect.EOF:
6327 main.log.error( self.name + ": EOF exception found" )
6328 main.log.error( self.name + ": " + self.handle.before )
6329 main.cleanAndExit()
6330 except Exception:
6331 main.log.exception( self.name + ": Uncaught exception!" )
6332 main.cleanAndExit()
6333
You Wang547893e2018-05-08 13:34:59 -07006334 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6335 """
6336 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6337 sAddr: we can provide * for ASM or a specific address for SSM
6338 gAddr: specifies multicast group address
6339 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6340 will delete the route if not specified
6341 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6342 """
6343 try:
6344 cmdStr = "mcast-sink-delete"
6345 cmdStr += " -sAddr " + str( sAddr )
6346 cmdStr += " -gAddr " + str( gAddr )
6347 if sink:
6348 cmdStr += " -s " + str( sink )
6349 handle = self.sendline( cmdStr )
6350 assert handle is not None, "Error in sendline"
6351 assert "Command not found:" not in handle, handle
6352 assert "Unsupported command:" not in handle, handle
6353 assert "Error executing command" not in handle, handle
6354 if "Updated the mcast route" in handle:
6355 return main.TRUE
6356 elif "Deleted the mcast route" in handle:
6357 return main.TRUE
6358 else:
6359 return main.FALSE
6360 except AssertionError:
6361 main.log.exception( "" )
6362 return None
6363 except TypeError:
6364 main.log.exception( self.name + ": Object not as expected" )
6365 return None
6366 except pexpect.EOF:
6367 main.log.error( self.name + ": EOF exception found" )
6368 main.log.error( self.name + ": " + self.handle.before )
6369 main.cleanAndExit()
6370 except Exception:
6371 main.log.exception( self.name + ": Uncaught exception!" )
6372 main.cleanAndExit()
6373
You Wange24d6272018-03-27 21:18:50 -07006374 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6375 """
6376 Delete multicast src(s) by calling 'mcast-source-delete' command
6377 sAddr: we can provide * for ASM or a specific address for SSM
6378 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006379 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 -07006380 will delete the route if not specified
6381 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6382 """
6383 try:
6384 cmdStr = "mcast-source-delete"
6385 cmdStr += " -sAddr " + str( sAddr )
6386 cmdStr += " -gAddr " + str( gAddr )
6387 if srcs:
6388 assert isinstance( srcs, list )
6389 for src in srcs:
6390 cmdStr += " -src " + str( src )
6391 handle = self.sendline( cmdStr )
6392 assert handle is not None, "Error in sendline"
6393 assert "Command not found:" not in handle, handle
6394 assert "Unsupported command:" not in handle, handle
6395 assert "Error executing command" not in handle, handle
6396 if "Updated the mcast route" in handle:
6397 return main.TRUE
6398 elif "Deleted the mcast route" in handle:
6399 return main.TRUE
6400 else:
6401 return main.FALSE
6402 except AssertionError:
6403 main.log.exception( "" )
6404 return None
6405 except TypeError:
6406 main.log.exception( self.name + ": Object not as expected" )
6407 return None
6408 except pexpect.EOF:
6409 main.log.error( self.name + ": EOF exception found" )
6410 main.log.error( self.name + ": " + self.handle.before )
6411 main.cleanAndExit()
6412 except Exception:
6413 main.log.exception( self.name + ": Uncaught exception!" )
6414 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006415
6416 def netcfg( self, jsonFormat=True, args="" ):
6417 """
6418 Run netcfg cli command with given args
6419 """
6420 try:
6421 cmdStr = "netcfg"
6422 if jsonFormat:
6423 cmdStr = cmdStr + " -j"
6424 if args:
6425 cmdStr = cmdStr + " " + str( args )
6426 handle = self.sendline( cmdStr )
6427 assert handle is not None, "Error in sendline"
6428 assert "Command not found:" not in handle, handle
6429 assert "Unsupported command:" not in handle, handle
6430 assert "Error executing command" not in handle, handle
6431 return handle
6432 except AssertionError:
6433 main.log.exception( "" )
6434 return None
6435 except TypeError:
6436 main.log.exception( self.name + ": Object not as expected" )
6437 return None
6438 except pexpect.EOF:
6439 main.log.error( self.name + ": EOF exception found" )
6440 main.log.error( self.name + ": " + self.handle.before )
6441 main.cleanAndExit()
6442 except Exception:
6443 main.log.exception( self.name + ": Uncaught exception!" )
6444 main.cleanAndExit()
6445
6446 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True ):
6447 """
6448 Compose and return t3-troubleshoot cli command for given source and destination addresses
6449 Options:
6450 sAddr: IP address of the source host
6451 dAddr: IP address of the destination host
6452 """
6453 try:
6454 # Collect information of both hosts from onos
6455 hosts = self.hosts()
6456 hosts = json.loads( hosts )
6457 sHost = None
6458 dHost = None
6459 for host in hosts:
6460 if sAddr in host[ "ipAddresses" ]:
6461 sHost = host
6462 elif dAddr in host[ "ipAddresses" ]:
6463 dHost = host
6464 if sHost and dHost:
6465 break
6466 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang5da39c82018-04-26 22:55:08 -07006467 cmdStr = "t3-troubleshoot"
6468 if verbose:
6469 cmdStr += " -vv"
6470 cmdStr += " -s " + str( sAddr )
6471 # TODO: collect t3 for all locations of source host?
6472 cmdStr += " -sp " + str( sHost[ "locations" ][ 0 ][ "elementId" ] ) + "/" + str( sHost[ "locations" ][ 0 ][ "port" ] )
6473 cmdStr += " -sm " + str( sHost[ "mac" ] )
You Wangc9faf4c2018-05-02 12:05:50 -07006474 if sHost[ "vlan" ] != "None":
6475 cmdStr += " -vid " + sHost[ "vlan" ]
You Wang5da39c82018-04-26 22:55:08 -07006476 cmdStr += " -d " + str( dAddr )
6477 netcfg = self.netcfg( args="devices {}".format( sHost[ "locations" ][ 0 ][ "elementId" ] ) )
6478 netcfg = json.loads( netcfg )
6479 assert netcfg, "Failed to get netcfg"
6480 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6481 if ipv6:
6482 cmdStr += " -et ipv6"
6483 return cmdStr
6484 except AssertionError:
6485 main.log.exception( "" )
6486 return None
6487 except ( KeyError, TypeError ):
6488 main.log.exception( self.name + ": Object not as expected" )
6489 return None
6490 except Exception:
6491 main.log.exception( self.name + ": Uncaught exception!" )
6492 main.cleanAndExit()
6493
6494 def t3( self, sAddr, dAddr, ipv6=False ):
6495 """
6496 Run t3-troubleshoot cli command for given source and destination addresses
6497 Options:
6498 sAddr: IP address of the source host
6499 dAddr: IP address of the destination host
6500 """
6501 try:
6502 cmdStr = self.composeT3Command( sAddr, dAddr, ipv6 )
6503 handle = self.sendline( cmdStr )
6504 assert handle is not None, "Error in sendline"
6505 assert "Command not found:" not in handle, handle
6506 assert "Unsupported command:" not in handle, handle
6507 assert "Error executing command" not in handle, handle
6508 assert "Tracing packet" in handle
6509 return handle
6510 except AssertionError:
6511 main.log.exception( "" )
6512 return None
6513 except pexpect.EOF:
6514 main.log.error( self.name + ": EOF exception found" )
6515 main.log.error( self.name + ": " + self.handle.before )
6516 main.cleanAndExit()
6517 except Exception:
6518 main.log.exception( self.name + ": Uncaught exception!" )
6519 main.cleanAndExit()