blob: 7af7e4f42a7eb2903410f66cd7fbb2f5aaaf9674 [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
1176 assert host, "Not able to find host with IP {}".format( hostIp )
1177 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:
1182 if loc in locDiscovered:
1183 discovered = True
1184 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
1185 break
1186 if discovered:
1187 locationsDiscovered.remove( locDiscovered )
1188 else:
1189 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1190 result = main.FALSE
1191 if locationsDiscovered:
1192 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1193 result = main.FALSE
1194 return result
1195 except KeyError:
1196 main.log.exception( self.name + ": host data not as expected: " + hosts )
1197 return None
1198 except pexpect.EOF:
1199 main.log.error( self.name + ": EOF exception found" )
1200 main.log.error( self.name + ": " + self.handle.before )
1201 main.cleanAndExit()
1202 except Exception:
1203 main.log.exception( self.name + ": Uncaught exception" )
1204 return None
1205
You Wang53dba1e2018-02-02 17:45:44 -08001206 def verifyHostIp( self, hostList=[], prefix="" ):
1207 """
1208 Description:
1209 Verify that all hosts have IP address assigned to them
1210 Optional:
1211 hostList: If specified, verifications only happen to the hosts
1212 in hostList
1213 prefix: at least one of the ip address assigned to the host
1214 needs to have the specified prefix
1215 Returns:
1216 main.TRUE if all hosts have specific IP address assigned;
1217 main.FALSE otherwise
1218 """
1219 import json
1220 try:
1221 hosts = self.hosts()
1222 hosts = json.loads( hosts )
1223 if not hostList:
1224 hostList = [ host[ "id" ] for host in hosts ]
1225 for host in hosts:
1226 hostId = host[ "id" ]
1227 if hostId not in hostList:
1228 continue
1229 ipList = host[ "ipAddresses" ]
1230 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1231 if not ipList:
1232 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1233 else:
1234 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1235 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1236 else:
1237 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1238 hostList.remove( hostId )
1239 if hostList:
1240 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1241 return main.FALSE
1242 else:
1243 return main.TRUE
1244 except KeyError:
1245 main.log.exception( self.name + ": host data not as expected: " + hosts )
1246 return None
1247 except pexpect.EOF:
1248 main.log.error( self.name + ": EOF exception found" )
1249 main.log.error( self.name + ": " + self.handle.before )
1250 main.cleanAndExit()
1251 except Exception:
1252 main.log.exception( self.name + ": Uncaught exception" )
1253 return None
1254
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001255 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001256 """
andrewonlabe6745342014-10-17 14:29:13 -04001257 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001258 * hostIdOne: ONOS host id for host1
1259 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001260 Optional:
1261 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001262 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001263 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001264 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001265 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001266 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001267 Returns:
1268 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001269 """
andrewonlabe6745342014-10-17 14:29:13 -04001270 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001271 cmdStr = "add-host-intent "
1272 if vlanId:
1273 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001274 if setVlan:
1275 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001276 if encap:
1277 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001278 if bandwidth:
1279 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001280 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001281 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001282 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001283 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001284 if re.search( "Error", handle ):
1285 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001286 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001287 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001288 else:
1289 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001290 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001291 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001292 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001293 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001294 else:
1295 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001296 main.log.debug( "Response from ONOS was: " +
1297 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001298 return None
Jon Hallc6793552016-01-19 14:18:37 -08001299 except AssertionError:
1300 main.log.exception( "" )
1301 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001302 except TypeError:
1303 main.log.exception( self.name + ": Object not as expected" )
1304 return None
andrewonlabe6745342014-10-17 14:29:13 -04001305 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001306 main.log.error( self.name + ": EOF exception found" )
1307 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001308 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001309 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001310 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001311 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001312
kelvin-onlabd3b64892015-01-20 13:26:24 -08001313 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001314 """
andrewonlab7b31d232014-10-24 13:31:47 -04001315 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001316 * ingressDevice: device id of ingress device
1317 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001318 Optional:
1319 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001320 Description:
1321 Adds an optical intent by specifying an ingress and egress device
1322 Returns:
1323 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001324 """
andrewonlab7b31d232014-10-24 13:31:47 -04001325 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001326 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1327 " " + str( egressDevice )
1328 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001329 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001330 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001331 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001332 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001333 main.log.error( "Error in adding Optical intent" )
1334 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001335 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001336 main.log.info( "Optical intent installed between " +
1337 str( ingressDevice ) + " and " +
1338 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001339 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001340 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001341 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001342 else:
1343 main.log.error( "Error, intent ID not found" )
1344 return None
Jon Hallc6793552016-01-19 14:18:37 -08001345 except AssertionError:
1346 main.log.exception( "" )
1347 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001348 except TypeError:
1349 main.log.exception( self.name + ": Object not as expected" )
1350 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001351 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001352 main.log.error( self.name + ": EOF exception found" )
1353 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001354 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001355 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001356 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001357 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001358
kelvin-onlabd3b64892015-01-20 13:26:24 -08001359 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001360 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001361 ingressDevice,
1362 egressDevice,
1363 portIngress="",
1364 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001365 ethType="",
1366 ethSrc="",
1367 ethDst="",
1368 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001369 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001370 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001371 ipProto="",
1372 ipSrc="",
1373 ipDst="",
1374 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001375 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001376 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001377 setVlan="",
1378 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001379 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001380 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001381 * ingressDevice: device id of ingress device
1382 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001383 Optional:
1384 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001385 * ethSrc: specify ethSrc ( i.e. src mac addr )
1386 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001387 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001388 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001389 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001390 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001391 * ipSrc: specify ip source address
1392 * ipDst: specify ip destination address
1393 * tcpSrc: specify tcp source port
1394 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001395 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001396 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001397 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001398 Description:
kelvin8ec71442015-01-15 16:57:00 -08001399 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001400 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001401 Returns:
1402 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001403
Jon Halle3f39ff2015-01-13 11:50:53 -08001404 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001405 options developers provide for point-to-point
1406 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001407 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001408 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001409 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001410
Jeremy Songsterff553672016-05-12 17:06:23 -07001411 if ethType:
1412 cmd += " --ethType " + str( ethType )
1413 if ethSrc:
1414 cmd += " --ethSrc " + str( ethSrc )
1415 if ethDst:
1416 cmd += " --ethDst " + str( ethDst )
1417 if bandwidth:
1418 cmd += " --bandwidth " + str( bandwidth )
1419 if lambdaAlloc:
1420 cmd += " --lambda "
1421 if ipProto:
1422 cmd += " --ipProto " + str( ipProto )
1423 if ipSrc:
1424 cmd += " --ipSrc " + str( ipSrc )
1425 if ipDst:
1426 cmd += " --ipDst " + str( ipDst )
1427 if tcpSrc:
1428 cmd += " --tcpSrc " + str( tcpSrc )
1429 if tcpDst:
1430 cmd += " --tcpDst " + str( tcpDst )
1431 if vlanId:
1432 cmd += " -v " + str( vlanId )
1433 if setVlan:
1434 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001435 if encap:
1436 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001437 if protected:
1438 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001439
kelvin8ec71442015-01-15 16:57:00 -08001440 # Check whether the user appended the port
1441 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001442 if "/" in ingressDevice:
1443 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001444 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001445 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001446 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001447 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001448 # Would it make sense to throw an exception and exit
1449 # the test?
1450 return None
andrewonlab36af3822014-11-18 17:48:18 -05001451
kelvin8ec71442015-01-15 16:57:00 -08001452 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001453 str( ingressDevice ) + "/" +\
1454 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001455
kelvin-onlabd3b64892015-01-20 13:26:24 -08001456 if "/" in egressDevice:
1457 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001458 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001459 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001460 main.log.error( "You must specify the egress port" )
1461 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001462
kelvin8ec71442015-01-15 16:57:00 -08001463 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001464 str( egressDevice ) + "/" +\
1465 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001466
kelvin-onlab898a6c62015-01-16 14:13:53 -08001467 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001468 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001469 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001470 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001471 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001472 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001473 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001474 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001475 # TODO: print out all the options in this message?
1476 main.log.info( "Point-to-point intent installed between " +
1477 str( ingressDevice ) + " and " +
1478 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001479 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001480 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001481 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001482 else:
1483 main.log.error( "Error, intent ID not found" )
1484 return None
Jon Hallc6793552016-01-19 14:18:37 -08001485 except AssertionError:
1486 main.log.exception( "" )
1487 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001488 except TypeError:
1489 main.log.exception( self.name + ": Object not as expected" )
1490 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001491 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001492 main.log.error( self.name + ": EOF exception found" )
1493 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001494 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001495 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001496 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001497 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001498
kelvin-onlabd3b64892015-01-20 13:26:24 -08001499 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001500 self,
shahshreyac2f97072015-03-19 17:04:29 -07001501 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001502 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001503 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001504 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001505 ethType="",
1506 ethSrc="",
1507 ethDst="",
1508 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001509 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001510 ipProto="",
1511 ipSrc="",
1512 ipDst="",
1513 tcpSrc="",
1514 tcpDst="",
1515 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001516 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001517 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001518 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001519 partial=False,
1520 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001521 """
shahshreyad0c80432014-12-04 16:56:05 -08001522 Note:
shahshreya70622b12015-03-19 17:19:00 -07001523 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001524 is same. That is, all ingress devices include port numbers
1525 with a "/" or all ingress devices could specify device
1526 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001527 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001528 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001529 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001530 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001531 Optional:
1532 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001533 * ethSrc: specify ethSrc ( i.e. src mac addr )
1534 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001535 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001536 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001537 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001538 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001539 * ipSrc: specify ip source address
1540 * ipDst: specify ip destination address
1541 * tcpSrc: specify tcp source port
1542 * tcpDst: specify tcp destination port
1543 * setEthSrc: action to Rewrite Source MAC Address
1544 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001545 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001546 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001547 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001548 Description:
kelvin8ec71442015-01-15 16:57:00 -08001549 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001550 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001551 Returns:
1552 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001553
Jon Halle3f39ff2015-01-13 11:50:53 -08001554 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001555 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001556 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001557 """
shahshreyad0c80432014-12-04 16:56:05 -08001558 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001559 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001560
Jeremy Songsterff553672016-05-12 17:06:23 -07001561 if ethType:
1562 cmd += " --ethType " + str( ethType )
1563 if ethSrc:
1564 cmd += " --ethSrc " + str( ethSrc )
1565 if ethDst:
1566 cmd += " --ethDst " + str( ethDst )
1567 if bandwidth:
1568 cmd += " --bandwidth " + str( bandwidth )
1569 if lambdaAlloc:
1570 cmd += " --lambda "
1571 if ipProto:
1572 cmd += " --ipProto " + str( ipProto )
1573 if ipSrc:
1574 cmd += " --ipSrc " + str( ipSrc )
1575 if ipDst:
1576 cmd += " --ipDst " + str( ipDst )
1577 if tcpSrc:
1578 cmd += " --tcpSrc " + str( tcpSrc )
1579 if tcpDst:
1580 cmd += " --tcpDst " + str( tcpDst )
1581 if setEthSrc:
1582 cmd += " --setEthSrc " + str( setEthSrc )
1583 if setEthDst:
1584 cmd += " --setEthDst " + str( setEthDst )
1585 if vlanId:
1586 cmd += " -v " + str( vlanId )
1587 if setVlan:
1588 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001589 if partial:
1590 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001591 if encap:
1592 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001593
kelvin8ec71442015-01-15 16:57:00 -08001594 # Check whether the user appended the port
1595 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001596
1597 if portIngressList is None:
1598 for ingressDevice in ingressDeviceList:
1599 if "/" in ingressDevice:
1600 cmd += " " + str( ingressDevice )
1601 else:
1602 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001603 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001604 # TODO: perhaps more meaningful return
1605 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001606 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001607 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001608 for ingressDevice, portIngress in zip( ingressDeviceList,
1609 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001610 cmd += " " + \
1611 str( ingressDevice ) + "/" +\
1612 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001613 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001614 main.log.error( "Device list and port list does not " +
1615 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001616 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001617 if "/" in egressDevice:
1618 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001619 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001620 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001621 main.log.error( "You must specify " +
1622 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001623 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001624
kelvin8ec71442015-01-15 16:57:00 -08001625 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001626 str( egressDevice ) + "/" +\
1627 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001628 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001629 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001630 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001631 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001632 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001633 main.log.error( "Error in adding multipoint-to-singlepoint " +
1634 "intent" )
1635 return None
shahshreyad0c80432014-12-04 16:56:05 -08001636 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001637 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001638 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001639 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001640 else:
1641 main.log.error( "Error, intent ID not found" )
1642 return None
Jon Hallc6793552016-01-19 14:18:37 -08001643 except AssertionError:
1644 main.log.exception( "" )
1645 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001646 except TypeError:
1647 main.log.exception( self.name + ": Object not as expected" )
1648 return None
1649 except pexpect.EOF:
1650 main.log.error( self.name + ": EOF exception found" )
1651 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001652 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001653 except Exception:
1654 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001655 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001656
1657 def addSinglepointToMultipointIntent(
1658 self,
1659 ingressDevice,
1660 egressDeviceList,
1661 portIngress="",
1662 portEgressList=None,
1663 ethType="",
1664 ethSrc="",
1665 ethDst="",
1666 bandwidth="",
1667 lambdaAlloc=False,
1668 ipProto="",
1669 ipSrc="",
1670 ipDst="",
1671 tcpSrc="",
1672 tcpDst="",
1673 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001674 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001675 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001676 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001677 partial=False,
1678 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001679 """
1680 Note:
1681 This function assumes the format of all egress devices
1682 is same. That is, all egress devices include port numbers
1683 with a "/" or all egress devices could specify device
1684 ids and port numbers seperately.
1685 Required:
1686 * EgressDeviceList: List of device ids of egress device
1687 ( Atleast 2 eress devices required in the list )
1688 * ingressDevice: device id of ingress device
1689 Optional:
1690 * ethType: specify ethType
1691 * ethSrc: specify ethSrc ( i.e. src mac addr )
1692 * ethDst: specify ethDst ( i.e. dst mac addr )
1693 * bandwidth: specify bandwidth capacity of link
1694 * lambdaAlloc: if True, intent will allocate lambda
1695 for the specified intent
1696 * ipProto: specify ip protocol
1697 * ipSrc: specify ip source address
1698 * ipDst: specify ip destination address
1699 * tcpSrc: specify tcp source port
1700 * tcpDst: specify tcp destination port
1701 * setEthSrc: action to Rewrite Source MAC Address
1702 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001703 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001704 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001705 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001706 Description:
1707 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1708 specifying device id's and optional fields
1709 Returns:
1710 A string of the intent id or None on error
1711
1712 NOTE: This function may change depending on the
1713 options developers provide for singlepoint-to-multipoint
1714 intent via cli
1715 """
1716 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001717 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001718
Jeremy Songsterff553672016-05-12 17:06:23 -07001719 if ethType:
1720 cmd += " --ethType " + str( ethType )
1721 if ethSrc:
1722 cmd += " --ethSrc " + str( ethSrc )
1723 if ethDst:
1724 cmd += " --ethDst " + str( ethDst )
1725 if bandwidth:
1726 cmd += " --bandwidth " + str( bandwidth )
1727 if lambdaAlloc:
1728 cmd += " --lambda "
1729 if ipProto:
1730 cmd += " --ipProto " + str( ipProto )
1731 if ipSrc:
1732 cmd += " --ipSrc " + str( ipSrc )
1733 if ipDst:
1734 cmd += " --ipDst " + str( ipDst )
1735 if tcpSrc:
1736 cmd += " --tcpSrc " + str( tcpSrc )
1737 if tcpDst:
1738 cmd += " --tcpDst " + str( tcpDst )
1739 if setEthSrc:
1740 cmd += " --setEthSrc " + str( setEthSrc )
1741 if setEthDst:
1742 cmd += " --setEthDst " + str( setEthDst )
1743 if vlanId:
1744 cmd += " -v " + str( vlanId )
1745 if setVlan:
1746 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001747 if partial:
1748 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001749 if encap:
1750 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001751
1752 # Check whether the user appended the port
1753 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001754
kelvin-onlabb9408212015-04-01 13:34:04 -07001755 if "/" in ingressDevice:
1756 cmd += " " + str( ingressDevice )
1757 else:
1758 if not portIngress:
1759 main.log.error( "You must specify " +
1760 "the Ingress port" )
1761 return main.FALSE
1762
1763 cmd += " " +\
1764 str( ingressDevice ) + "/" +\
1765 str( portIngress )
1766
1767 if portEgressList is None:
1768 for egressDevice in egressDeviceList:
1769 if "/" in egressDevice:
1770 cmd += " " + str( egressDevice )
1771 else:
1772 main.log.error( "You must specify " +
1773 "the egress port" )
1774 # TODO: perhaps more meaningful return
1775 return main.FALSE
1776 else:
1777 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001778 for egressDevice, portEgress in zip( egressDeviceList,
1779 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001780 cmd += " " + \
1781 str( egressDevice ) + "/" +\
1782 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001783 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001784 main.log.error( "Device list and port list does not " +
1785 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001786 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001787 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001788 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001789 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001790 # If error, return error message
1791 if re.search( "Error", handle ):
1792 main.log.error( "Error in adding singlepoint-to-multipoint " +
1793 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001794 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001795 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001796 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001797 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001798 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001799 else:
1800 main.log.error( "Error, intent ID not found" )
1801 return None
Jon Hallc6793552016-01-19 14:18:37 -08001802 except AssertionError:
1803 main.log.exception( "" )
1804 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001805 except TypeError:
1806 main.log.exception( self.name + ": Object not as expected" )
1807 return None
shahshreyad0c80432014-12-04 16:56:05 -08001808 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001809 main.log.error( self.name + ": EOF exception found" )
1810 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001811 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001812 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001813 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001814 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001815
Hari Krishna9e232602015-04-13 17:29:08 -07001816 def addMplsIntent(
1817 self,
1818 ingressDevice,
1819 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001820 ingressPort="",
1821 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001822 ethType="",
1823 ethSrc="",
1824 ethDst="",
1825 bandwidth="",
1826 lambdaAlloc=False,
1827 ipProto="",
1828 ipSrc="",
1829 ipDst="",
1830 tcpSrc="",
1831 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001832 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001833 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001834 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001835 """
1836 Required:
1837 * ingressDevice: device id of ingress device
1838 * egressDevice: device id of egress device
1839 Optional:
1840 * ethType: specify ethType
1841 * ethSrc: specify ethSrc ( i.e. src mac addr )
1842 * ethDst: specify ethDst ( i.e. dst mac addr )
1843 * bandwidth: specify bandwidth capacity of link
1844 * lambdaAlloc: if True, intent will allocate lambda
1845 for the specified intent
1846 * ipProto: specify ip protocol
1847 * ipSrc: specify ip source address
1848 * ipDst: specify ip destination address
1849 * tcpSrc: specify tcp source port
1850 * tcpDst: specify tcp destination port
1851 * ingressLabel: Ingress MPLS label
1852 * egressLabel: Egress MPLS label
1853 Description:
1854 Adds MPLS intent by
1855 specifying device id's and optional fields
1856 Returns:
1857 A string of the intent id or None on error
1858
1859 NOTE: This function may change depending on the
1860 options developers provide for MPLS
1861 intent via cli
1862 """
1863 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001864 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001865
Jeremy Songsterff553672016-05-12 17:06:23 -07001866 if ethType:
1867 cmd += " --ethType " + str( ethType )
1868 if ethSrc:
1869 cmd += " --ethSrc " + str( ethSrc )
1870 if ethDst:
1871 cmd += " --ethDst " + str( ethDst )
1872 if bandwidth:
1873 cmd += " --bandwidth " + str( bandwidth )
1874 if lambdaAlloc:
1875 cmd += " --lambda "
1876 if ipProto:
1877 cmd += " --ipProto " + str( ipProto )
1878 if ipSrc:
1879 cmd += " --ipSrc " + str( ipSrc )
1880 if ipDst:
1881 cmd += " --ipDst " + str( ipDst )
1882 if tcpSrc:
1883 cmd += " --tcpSrc " + str( tcpSrc )
1884 if tcpDst:
1885 cmd += " --tcpDst " + str( tcpDst )
1886 if ingressLabel:
1887 cmd += " --ingressLabel " + str( ingressLabel )
1888 if egressLabel:
1889 cmd += " --egressLabel " + str( egressLabel )
1890 if priority:
1891 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001892
1893 # Check whether the user appended the port
1894 # or provided it as an input
1895 if "/" in ingressDevice:
1896 cmd += " " + str( ingressDevice )
1897 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001898 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001899 main.log.error( "You must specify the ingress port" )
1900 return None
1901
1902 cmd += " " + \
1903 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001904 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001905
1906 if "/" in egressDevice:
1907 cmd += " " + str( egressDevice )
1908 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001909 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001910 main.log.error( "You must specify the egress port" )
1911 return None
1912
1913 cmd += " " +\
1914 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001915 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001916
1917 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001918 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001919 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001920 # If error, return error message
1921 if re.search( "Error", handle ):
1922 main.log.error( "Error in adding mpls intent" )
1923 return None
1924 else:
1925 # TODO: print out all the options in this message?
1926 main.log.info( "MPLS intent installed between " +
1927 str( ingressDevice ) + " and " +
1928 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001929 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07001930 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001931 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07001932 else:
1933 main.log.error( "Error, intent ID not found" )
1934 return None
Jon Hallc6793552016-01-19 14:18:37 -08001935 except AssertionError:
1936 main.log.exception( "" )
1937 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001938 except TypeError:
1939 main.log.exception( self.name + ": Object not as expected" )
1940 return None
1941 except pexpect.EOF:
1942 main.log.error( self.name + ": EOF exception found" )
1943 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001944 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001945 except Exception:
1946 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001947 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001948
Jon Hallefbd9792015-03-05 16:11:36 -08001949 def removeIntent( self, intentId, app='org.onosproject.cli',
1950 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001951 """
shahshreya1c818fc2015-02-26 13:44:08 -08001952 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001953 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001954 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001955 -p or --purge: Purge the intent from the store after removal
1956
Jon Halle3f39ff2015-01-13 11:50:53 -08001957 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001958 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001959 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001960 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001961 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001962 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001963 if purge:
1964 cmdStr += " -p"
1965 if sync:
1966 cmdStr += " -s"
1967
1968 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001969 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001970 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001971 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001972 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001973 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001974 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001975 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001976 # TODO: Should this be main.TRUE
1977 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001978 except AssertionError:
1979 main.log.exception( "" )
1980 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001981 except TypeError:
1982 main.log.exception( self.name + ": Object not as expected" )
1983 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001984 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001985 main.log.error( self.name + ": EOF exception found" )
1986 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001987 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001988 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001989 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001990 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04001991
YPZhangfebf7302016-05-24 16:45:56 -07001992 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001993 """
1994 Description:
1995 Remove all the intents
1996 Optional args:-
1997 -s or --sync: Waits for the removal before returning
1998 -p or --purge: Purge the intent from the store after removal
1999 Returns:
2000 Returns main.TRUE if all intents are removed, otherwise returns
2001 main.FALSE; Returns None for exception
2002 """
2003 try:
2004 cmdStr = "remove-intent"
2005 if purge:
2006 cmdStr += " -p"
2007 if sync:
2008 cmdStr += " -s"
2009
2010 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002011 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002012 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002013 assert "Command not found:" not in handle, handle
2014 if re.search( "Error", handle ):
2015 main.log.error( "Error in removing intent" )
2016 return main.FALSE
2017 else:
2018 return main.TRUE
2019 except AssertionError:
2020 main.log.exception( "" )
2021 return None
2022 except TypeError:
2023 main.log.exception( self.name + ": Object not as expected" )
2024 return None
2025 except pexpect.EOF:
2026 main.log.error( self.name + ": EOF exception found" )
2027 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002028 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002029 except Exception:
2030 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002031 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002032
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002033 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002034 """
2035 Purges all WITHDRAWN Intents
2036 """
2037 try:
2038 cmdStr = "purge-intents"
2039 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002040 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002041 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002042 if re.search( "Error", handle ):
2043 main.log.error( "Error in purging intents" )
2044 return main.FALSE
2045 else:
2046 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002047 except AssertionError:
2048 main.log.exception( "" )
2049 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002050 except TypeError:
2051 main.log.exception( self.name + ": Object not as expected" )
2052 return None
2053 except pexpect.EOF:
2054 main.log.error( self.name + ": EOF exception found" )
2055 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002056 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002057 except Exception:
2058 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002059 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002060
Devin Lime6fe3c42017-10-18 16:28:40 -07002061 def wipeout( self ):
2062 """
2063 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2064 """
2065 try:
2066 cmdStr = "wipe-out please"
2067 handle = self.sendline( cmdStr, timeout=60 )
2068 assert handle is not None, "Error in sendline"
2069 assert "Command not found:" not in handle, handle
2070 return main.TRUE
2071 except AssertionError:
2072 main.log.exception( "" )
2073 return None
2074 except TypeError:
2075 main.log.exception( self.name + ": Object not as expected" )
2076 return None
2077 except pexpect.EOF:
2078 main.log.error( self.name + ": EOF exception found" )
2079 main.log.error( self.name + ": " + self.handle.before )
2080 main.cleanAndExit()
2081 except Exception:
2082 main.log.exception( self.name + ": Uncaught exception!" )
2083 main.cleanAndExit()
2084
kelvin-onlabd3b64892015-01-20 13:26:24 -08002085 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002086 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002087 NOTE: This method should be used after installing application:
2088 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002089 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002090 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002091 Description:
2092 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002093 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002094 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002095 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002096 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002097 cmdStr += " -j"
2098 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002099 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002100 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002101 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002102 except AssertionError:
2103 main.log.exception( "" )
2104 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002105 except TypeError:
2106 main.log.exception( self.name + ": Object not as expected" )
2107 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002108 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002109 main.log.error( self.name + ": EOF exception found" )
2110 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002111 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002112 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002113 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002114 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002115
pingping-lin54b03372015-08-13 14:43:10 -07002116 def ipv4RouteNumber( self ):
2117 """
2118 NOTE: This method should be used after installing application:
2119 onos-app-sdnip
2120 Description:
2121 Obtain the total IPv4 routes number in the system
2122 """
2123 try:
Pratik Parab57963572017-05-09 11:37:54 -07002124 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002125 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002126 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002127 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002128 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002129 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002130 except AssertionError:
2131 main.log.exception( "" )
2132 return None
2133 except ( TypeError, ValueError ):
2134 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002135 return None
2136 except pexpect.EOF:
2137 main.log.error( self.name + ": EOF exception found" )
2138 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002139 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002140 except Exception:
2141 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002142 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002143
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002144 # =============Function to check Bandwidth allocation========
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002145 def allocations( self, jsonFormat = True, dollarSign = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002146 """
2147 Description:
2148 Obtain Bandwidth Allocation Information from ONOS cli.
2149 """
2150 try:
2151 cmdStr = "allocations"
2152 if jsonFormat:
2153 cmdStr += " -j"
2154 handle = self.sendline( cmdStr, timeout=300, dollarSign=True )
2155 assert handle is not None, "Error in sendline"
2156 assert "Command not found:" not in handle, handle
2157 return handle
2158 except AssertionError:
2159 main.log.exception( "" )
2160 return None
2161 except ( TypeError, ValueError ):
2162 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2163 return None
2164 except pexpect.EOF:
2165 main.log.error( self.name + ": EOF exception found" )
2166 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002167 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002168 except Exception:
2169 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002170 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002171
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002172 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002173 """
andrewonlabe6745342014-10-17 14:29:13 -04002174 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002175 Obtain intents from the ONOS cli.
2176 Optional:
2177 * jsonFormat: Enable output formatting in json, default to True
2178 * summary: Whether only output the intent summary, defaults to False
2179 * type: Only output a certain type of intent. This options is valid
2180 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002181 """
andrewonlabe6745342014-10-17 14:29:13 -04002182 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002183 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002184 if summary:
2185 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002186 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002187 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002188 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002189 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002190 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002191 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002192 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002193 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002194 else:
Jon Hallff566d52016-01-15 14:45:36 -08002195 intentType = ""
2196 # IF we want the summary of a specific intent type
2197 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002198 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002199 if intentType in jsonResult.keys():
2200 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002201 else:
Jon Hallff566d52016-01-15 14:45:36 -08002202 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002203 return handle
2204 else:
2205 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002206 except AssertionError:
2207 main.log.exception( "" )
2208 return None
2209 except ( TypeError, ValueError ):
2210 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002211 return None
2212 except pexpect.EOF:
2213 main.log.error( self.name + ": EOF exception found" )
2214 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002215 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002216 except Exception:
2217 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002218 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002219
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002220 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002221 """
You Wangfdcbfc42016-05-16 12:16:53 -07002222 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002223 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002224 list of intent IDs.
2225 Parameters:
2226 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002227 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002228 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002229 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002230 accepted.
2231 Returns a list of dictionaries if a list of intent IDs is accepted,
2232 and each dictionary maps 'id' to the Intent ID and 'state' to
2233 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002234 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002235
kelvin-onlab54400a92015-02-26 18:05:51 -08002236 try:
2237 state = "State is Undefined"
2238 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002239 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002240 else:
Jon Hallc6793552016-01-19 14:18:37 -08002241 rawJson = intentsJson
2242 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002243 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002244 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002245 if intentsId == intent[ 'id' ]:
2246 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002247 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002248 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002249 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002250 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002251 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002252 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002253 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002254 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002255 for intent in parsedIntentsJson:
2256 if intentsId[ i ] == intent[ 'id' ]:
2257 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002258 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002259 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002260 break
Jon Hallefbd9792015-03-05 16:11:36 -08002261 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002262 main.log.warn( "Could not find all intents in ONOS output" )
2263 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002264 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002265 else:
Jon Hall53158082017-05-18 11:17:00 -07002266 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002267 return None
Jon Hallc6793552016-01-19 14:18:37 -08002268 except ( TypeError, ValueError ):
2269 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002270 return None
2271 except pexpect.EOF:
2272 main.log.error( self.name + ": EOF exception found" )
2273 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002274 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002275 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002276 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002277 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002278
Jon Hallf539eb92017-05-22 17:18:42 -07002279 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002280 """
2281 Description:
2282 Check intents state
2283 Required:
2284 intentsId - List of intents ID to be checked
2285 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002286 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002287 state in the list.
2288 *NOTE: You can pass in a list of expected state,
2289 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002290 Return:
Jon Hall53158082017-05-18 11:17:00 -07002291 Returns main.TRUE only if all intent are the same as expected states,
2292 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002293 """
2294 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002295 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002296 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002297
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002298 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002299 intentsDict = []
2300 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002301 if isinstance( intentsId, types.StringType ) \
2302 and intent.get( 'id' ) == intentsId:
2303 intentsDict.append( intent )
2304 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002305 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002306 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002307
2308 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002309 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002310 "getting intents state" )
2311 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002312
2313 if isinstance( expectedState, types.StringType ):
2314 for intents in intentsDict:
2315 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002316 main.log.debug( self.name + " : Intent ID - " +
2317 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002318 " actual state = " +
2319 intents.get( 'state' )
2320 + " does not equal expected state = "
2321 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002322 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002323 elif isinstance( expectedState, types.ListType ):
2324 for intents in intentsDict:
2325 if not any( state == intents.get( 'state' ) for state in
2326 expectedState ):
2327 main.log.debug( self.name + " : Intent ID - " +
2328 intents.get( 'id' ) +
2329 " actual state = " +
2330 intents.get( 'state' ) +
2331 " does not equal expected states = "
2332 + str( expectedState ) )
2333 returnValue = main.FALSE
2334
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002335 if returnValue == main.TRUE:
2336 main.log.info( self.name + ": All " +
2337 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002338 " intents are in " + str( expectedState ) +
2339 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002340 return returnValue
2341 except TypeError:
2342 main.log.exception( self.name + ": Object not as expected" )
2343 return None
2344 except pexpect.EOF:
2345 main.log.error( self.name + ": EOF exception found" )
2346 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002347 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002348 except Exception:
2349 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002350 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002351
Jon Hallf539eb92017-05-22 17:18:42 -07002352 def compareBandwidthAllocations( self, expectedAllocations ):
2353 """
2354 Description:
2355 Compare the allocated bandwidth with the given allocations
2356 Required:
2357 expectedAllocations - The expected ONOS output of the allocations command
2358 Return:
2359 Returns main.TRUE only if all intent are the same as expected states,
2360 otherwise returns main.FALSE.
2361 """
2362 # FIXME: Convert these string comparisons to object comparisons
2363 try:
2364 returnValue = main.TRUE
2365 bandwidthFailed = False
2366 rawAlloc = self.allocations()
2367 expectedFormat = StringIO( expectedAllocations )
2368 ONOSOutput = StringIO( rawAlloc )
2369 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2370 str( expectedFormat ) ) )
2371
2372 for actual, expected in izip( ONOSOutput, expectedFormat ):
2373 actual = actual.rstrip()
2374 expected = expected.rstrip()
2375 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2376 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002377 marker1 = actual.find( 'allocated' )
2378 m1 = actual[ :marker1 ]
2379 marker2 = expected.find( 'allocated' )
2380 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002381 if m1 != m2:
2382 bandwidthFailed = True
2383 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2384 bandwidthFailed = True
2385 expectedFormat.close()
2386 ONOSOutput.close()
2387
2388 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002389 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002390 returnValue = main.FALSE
2391 return returnValue
2392 except TypeError:
2393 main.log.exception( self.name + ": Object not as expected" )
2394 return None
2395 except pexpect.EOF:
2396 main.log.error( self.name + ": EOF exception found" )
2397 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002398 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002399 except Exception:
2400 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002401 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002402
You Wang66518af2016-05-16 15:32:59 -07002403 def compareIntent( self, intentDict ):
2404 """
2405 Description:
2406 Compare the intent ids and states provided in the argument with all intents in ONOS
2407 Return:
2408 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2409 Arguments:
2410 intentDict: a dictionary which maps intent ids to intent states
2411 """
2412 try:
2413 intentsRaw = self.intents()
2414 intentsJson = json.loads( intentsRaw )
2415 intentDictONOS = {}
2416 for intent in intentsJson:
2417 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002418 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002419 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002420 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002421 str( len( intentDict ) ) + " expected and " +
2422 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002423 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002424 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002425 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002426 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2427 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002428 else:
2429 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2430 main.log.debug( self.name + ": intent ID - " + intentID +
2431 " expected state is " + intentDict[ intentID ] +
2432 " but actual state is " + intentDictONOS[ intentID ] )
2433 returnValue = main.FALSE
2434 intentDictONOS.pop( intentID )
2435 if len( intentDictONOS ) > 0:
2436 returnValue = main.FALSE
2437 for intentID in intentDictONOS.keys():
2438 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002439 if returnValue == main.TRUE:
2440 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2441 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002442 except KeyError:
2443 main.log.exception( self.name + ": KeyError exception found" )
2444 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002445 except ( TypeError, ValueError ):
2446 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002447 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002448 except pexpect.EOF:
2449 main.log.error( self.name + ": EOF exception found" )
2450 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002451 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002452 except Exception:
2453 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002454 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002455
YPZhang14a4aa92016-07-15 13:37:15 -07002456 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002457 """
2458 Description:
2459 Check the number of installed intents.
2460 Optional:
2461 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002462 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002463 Return:
2464 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2465 , otherwise, returns main.FALSE.
2466 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002467
GlennRCed771242016-01-13 17:02:47 -08002468 try:
2469 cmd = "intents -s -j"
2470
2471 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002472 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002473 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002474 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002475 response = json.loads( response )
2476
2477 # get total and installed number, see if they are match
2478 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002479 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002480 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2481 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002482 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002483 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2484 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002485 return main.FALSE
2486
Jon Hallc6793552016-01-19 14:18:37 -08002487 except ( TypeError, ValueError ):
2488 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002489 return None
2490 except pexpect.EOF:
2491 main.log.error( self.name + ": EOF exception found" )
2492 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002493 if noExit:
2494 return main.FALSE
2495 else:
Devin Lim44075962017-08-11 10:56:37 -07002496 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002497 except pexpect.TIMEOUT:
2498 main.log.error( self.name + ": ONOS timeout" )
2499 return None
GlennRCed771242016-01-13 17:02:47 -08002500 except Exception:
2501 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002502 if noExit:
2503 return main.FALSE
2504 else:
Devin Lim44075962017-08-11 10:56:37 -07002505 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002506
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002507 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002508 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002509 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002510 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002511 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002512 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002513 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002514 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002515 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002516 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002517 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002518 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002519 if noCore:
2520 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002521 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002522 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002523 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002524 assert "Command not found:" not in handle, handle
2525 if re.search( "Error:", handle ):
2526 main.log.error( self.name + ": flows() response: " +
2527 str( handle ) )
2528 return handle
2529 except AssertionError:
2530 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002531 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002532 except TypeError:
2533 main.log.exception( self.name + ": Object not as expected" )
2534 return None
Jon Hallc6793552016-01-19 14:18:37 -08002535 except pexpect.TIMEOUT:
2536 main.log.error( self.name + ": ONOS timeout" )
2537 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002538 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002539 main.log.error( self.name + ": EOF exception found" )
2540 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002541 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002542 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002543 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002544 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002545
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002546 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002547 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002548 count = int( count ) if count else 0
2549 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002550
Jon Halle0f0b342017-04-18 11:43:47 -07002551 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002552 """
2553 Description:
GlennRCed771242016-01-13 17:02:47 -08002554 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002555 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2556 if the count of those states is 0, which means all current flows
2557 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002558 Optional:
GlennRCed771242016-01-13 17:02:47 -08002559 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002560 Return:
2561 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002562 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002563 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002564 """
2565 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002566 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002567 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002568 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002569 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002570 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002571 if rawFlows:
2572 # if we didn't get flows or flows function return None, we should return
2573 # main.Flase
2574 checkedStates.append( json.loads( rawFlows ) )
2575 else:
2576 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002577 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002578 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002579 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002580 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002581 except TypeError:
2582 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002583 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002584
GlennRCed771242016-01-13 17:02:47 -08002585 # We want to count PENDING_ADD if isPENDING is true
2586 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002587 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002588 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002589 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002590 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002591 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002592 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002593 except ( TypeError, ValueError ):
2594 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002595 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002596
YPZhang240842b2016-05-17 12:00:50 -07002597 except AssertionError:
2598 main.log.exception( "" )
2599 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002600 except pexpect.TIMEOUT:
2601 main.log.error( self.name + ": ONOS timeout" )
2602 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002603 except pexpect.EOF:
2604 main.log.error( self.name + ": EOF exception found" )
2605 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002606 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002607 except Exception:
2608 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002609 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002610
GlennRCed771242016-01-13 17:02:47 -08002611 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002612 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002613 """
andrewonlab87852b02014-11-19 18:44:19 -05002614 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002615 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002616 a specific point-to-point intent definition
2617 Required:
GlennRCed771242016-01-13 17:02:47 -08002618 * ingress: specify source dpid
2619 * egress: specify destination dpid
2620 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002621 Optional:
GlennRCed771242016-01-13 17:02:47 -08002622 * offset: the keyOffset is where the next batch of intents
2623 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002624 * noExit: If set to True, TestON will not exit if any error when issus command
2625 * getResponse: If set to True, function will return ONOS response.
2626
GlennRCed771242016-01-13 17:02:47 -08002627 Returns: If failed to push test intents, it will returen None,
2628 if successful, return true.
2629 Timeout expection will return None,
2630 TypeError will return false
2631 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002632 """
andrewonlab87852b02014-11-19 18:44:19 -05002633 try:
GlennRCed771242016-01-13 17:02:47 -08002634 if background:
2635 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002636 else:
GlennRCed771242016-01-13 17:02:47 -08002637 back = ""
2638 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002639 ingress,
2640 egress,
2641 batchSize,
2642 offset,
2643 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002644 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002645 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002646 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002647 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002648 if getResponse:
2649 return response
2650
GlennRCed771242016-01-13 17:02:47 -08002651 # TODO: We should handle if there is failure in installation
2652 return main.TRUE
2653
Jon Hallc6793552016-01-19 14:18:37 -08002654 except AssertionError:
2655 main.log.exception( "" )
2656 return None
GlennRCed771242016-01-13 17:02:47 -08002657 except pexpect.TIMEOUT:
2658 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002659 return None
andrewonlab87852b02014-11-19 18:44:19 -05002660 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002661 main.log.error( self.name + ": EOF exception found" )
2662 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002663 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002664 except TypeError:
2665 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002666 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002667 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002668 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002669 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002670
YPZhangebf9eb52016-05-12 15:20:24 -07002671 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002672 """
2673 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002674 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002675 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002676 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002677 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002678 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002679
YPZhangb5d3f832016-01-23 22:54:26 -08002680 try:
YPZhange3109a72016-02-02 11:25:37 -08002681 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002682 cmd = "flows -c added"
2683 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2684 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002685 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002686 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002687 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002688 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002689 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002690 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002691 return None
2692 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002693
You Wangd3cb2ce2016-05-16 14:01:24 -07002694 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002695 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002696 return None
2697 except pexpect.EOF:
2698 main.log.error( self.name + ": EOF exception found" )
2699 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002700 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002701 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002702 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002703 except pexpect.TIMEOUT:
2704 main.log.error( self.name + ": ONOS timeout" )
2705 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002706 except Exception:
2707 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002708 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002709 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002710 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002711
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002712 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002713 """
2714 Description:
2715 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002716 Optional:
2717 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002718 Return:
2719 The number of intents
2720 """
2721 try:
2722 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002723 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002724 if response is None:
2725 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002726 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002727 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002728 except ( TypeError, ValueError ):
2729 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002730 return None
2731 except pexpect.EOF:
2732 main.log.error( self.name + ": EOF exception found" )
2733 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002734 if noExit:
2735 return -1
2736 else:
Devin Lim44075962017-08-11 10:56:37 -07002737 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002738 except Exception:
2739 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002740 if noExit:
2741 return -1
2742 else:
Devin Lim44075962017-08-11 10:56:37 -07002743 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002744
kelvin-onlabd3b64892015-01-20 13:26:24 -08002745 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002746 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002747 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002748 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002749 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002750 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002751 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002752 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002753 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002754 cmdStr += " -j"
2755 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002756 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002757 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002758 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002759 except AssertionError:
2760 main.log.exception( "" )
2761 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002762 except TypeError:
2763 main.log.exception( self.name + ": Object not as expected" )
2764 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002765 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002766 main.log.error( self.name + ": EOF exception found" )
2767 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002768 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002769 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002770 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002771 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002772
kelvin-onlabd3b64892015-01-20 13:26:24 -08002773 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002774 """
2775 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002776 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002777 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002778 """
andrewonlab867212a2014-10-22 20:13:38 -04002779 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002780 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002781 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002782 cmdStr += " -j"
2783 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002784 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002785 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002786 if handle:
2787 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002788 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002789 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002790 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002791 else:
2792 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002793 except AssertionError:
2794 main.log.exception( "" )
2795 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002796 except TypeError:
2797 main.log.exception( self.name + ": Object not as expected" )
2798 return None
andrewonlab867212a2014-10-22 20:13:38 -04002799 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002800 main.log.error( self.name + ": EOF exception found" )
2801 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002802 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002803 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002804 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002805 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002806
kelvin8ec71442015-01-15 16:57:00 -08002807 # Wrapper functions ****************
2808 # Wrapper functions use existing driver
2809 # functions and extends their use case.
2810 # For example, we may use the output of
2811 # a normal driver function, and parse it
2812 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002813
kelvin-onlabd3b64892015-01-20 13:26:24 -08002814 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002815 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002816 Description:
2817 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002818 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002819 try:
kelvin8ec71442015-01-15 16:57:00 -08002820 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002821 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002822 if intentsStr is None:
2823 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002824 # Convert to a dictionary
2825 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002826 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002827 for intent in intents:
2828 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002829 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002830 except TypeError:
2831 main.log.exception( self.name + ": Object not as expected" )
2832 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002833 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002834 main.log.error( self.name + ": EOF exception found" )
2835 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002836 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002837 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002838 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002839 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002840
You Wang3c276252016-09-21 15:21:36 -07002841 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002842 """
2843 Determine the number of flow rules for the given device id that are
2844 in the added state
You Wang3c276252016-09-21 15:21:36 -07002845 Params:
2846 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002847 """
2848 try:
You Wang3c276252016-09-21 15:21:36 -07002849 if core:
2850 cmdStr = "flows any " + str( deviceId ) + " | " +\
2851 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2852 else:
2853 cmdStr = "flows any " + str( deviceId ) + " | " +\
2854 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002855 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002856 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002857 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002858 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002859 except AssertionError:
2860 main.log.exception( "" )
2861 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002862 except pexpect.EOF:
2863 main.log.error( self.name + ": EOF exception found" )
2864 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002865 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002866 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002867 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002868 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002869
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002870 def groupAddedCount( self, deviceId, core=False ):
2871 """
2872 Determine the number of group rules for the given device id that are
2873 in the added state
2874 Params:
2875 core: if True, only return the number of core groups added
2876 """
2877 try:
2878 if core:
2879 cmdStr = "groups any " + str( deviceId ) + " | " +\
2880 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2881 else:
2882 cmdStr = "groups any " + str( deviceId ) + " | " +\
2883 "grep 'state=ADDED' | wc -l"
2884 handle = self.sendline( cmdStr )
2885 assert handle is not None, "Error in sendline"
2886 assert "Command not found:" not in handle, handle
2887 return handle
2888 except AssertionError:
2889 main.log.exception( "" )
2890 return None
2891 except pexpect.EOF:
2892 main.log.error( self.name + ": EOF exception found" )
2893 main.log.error( self.name + ": " + self.handle.before )
2894 main.cleanAndExit()
2895 except Exception:
2896 main.log.exception( self.name + ": Uncaught exception!" )
2897 main.cleanAndExit()
2898
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002899 def addStaticRoute( self, subnet, intf):
2900 """
2901 Adds a static route to onos.
2902 Params:
2903 subnet: The subnet reaching through this route
2904 intf: The interface this route is reachable through
2905 """
2906 try:
2907 cmdStr = "route-add " + subnet + " " + intf
2908 handle = self.sendline( cmdStr )
2909 assert handle is not None, "Error in sendline"
2910 assert "Command not found:" not in handle, handle
2911 return handle
2912 except AssertionError:
2913 main.log.exception( "" )
2914 return None
2915 except pexpect.EOF:
2916 main.log.error( self.name + ": EOF exception found" )
2917 main.log.error( self.name + ": " + self.handle.before )
2918 main.cleanAndExit()
2919 except Exception:
2920 main.log.exception( self.name + ": Uncaught exception!" )
2921 main.cleanAndExit()
2922
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002923 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
2924 """
2925 Description:
2926 Check whether the number of groups for the given device id that
2927 are in ADDED state is bigger than minGroupCount.
2928 Required:
2929 * deviceId: device id to check the number of added group rules
2930 Optional:
2931 * minGroupCount: the number of groups to compare
2932 * core: if True, only check the number of core groups added
2933 * comparison: if 0, compare with greater than minFlowCount
2934 * if 1, compare with equal to minFlowCount
2935 Return:
2936 Returns the number of groups if it is bigger than minGroupCount,
2937 returns main.FALSE otherwise.
2938 """
2939 count = self.groupAddedCount( deviceId, core )
2940 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07002941 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002942 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
2943
2944 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002945 """
2946 Description:
2947 Check whether the number of flow rules for the given device id that
2948 are in ADDED state is bigger than minFlowCount.
2949 Required:
2950 * deviceId: device id to check the number of added flow rules
2951 Optional:
2952 * minFlowCount: the number of flow rules to compare
2953 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002954 * comparison: if 0, compare with greater than minFlowCount
2955 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002956 Return:
2957 Returns the number of flow rules if it is bigger than minFlowCount,
2958 returns main.FALSE otherwise.
2959 """
2960 count = self.flowAddedCount( deviceId, core )
2961 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07002962 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002963 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002964
kelvin-onlabd3b64892015-01-20 13:26:24 -08002965 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002966 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002967 Use 'devices' function to obtain list of all devices
2968 and parse the result to obtain a list of all device
2969 id's. Returns this list. Returns empty list if no
2970 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002971 List is ordered sequentially
2972
andrewonlab3e15ead2014-10-15 14:21:34 -04002973 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002974 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002975 the ids. By obtaining the list of device ids on the fly,
2976 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002977 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002978 try:
kelvin8ec71442015-01-15 16:57:00 -08002979 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002980 devicesStr = self.devices( jsonFormat=False )
2981 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002982
kelvin-onlabd3b64892015-01-20 13:26:24 -08002983 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002984 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002985 return idList
kelvin8ec71442015-01-15 16:57:00 -08002986
2987 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002988 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002989 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002990 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002991 # Split list further into arguments before and after string
2992 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002993 # append to idList
2994 for arg in tempList:
2995 idList.append( arg.split( "id=" )[ 1 ] )
2996 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002997
Jon Halld4d4b372015-01-28 16:02:41 -08002998 except TypeError:
2999 main.log.exception( self.name + ": Object not as expected" )
3000 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003001 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003002 main.log.error( self.name + ": EOF exception found" )
3003 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003004 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003005 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003006 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003007 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003008
kelvin-onlabd3b64892015-01-20 13:26:24 -08003009 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003010 """
andrewonlab7c211572014-10-15 16:45:20 -04003011 Uses 'nodes' function to obtain list of all nodes
3012 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003013 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003014 Returns:
3015 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003016 """
andrewonlab7c211572014-10-15 16:45:20 -04003017 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003018 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003019 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003020 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003021 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003022 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003023 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003024 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003025 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003026 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003027 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003028 except ( TypeError, ValueError ):
3029 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003030 return None
andrewonlab7c211572014-10-15 16:45:20 -04003031 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003032 main.log.error( self.name + ": EOF exception found" )
3033 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003034 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003035 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003036 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003037 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003038
kelvin-onlabd3b64892015-01-20 13:26:24 -08003039 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003040 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003041 Return the first device from the devices api whose 'id' contains 'dpid'
3042 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003043 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003044 try:
kelvin8ec71442015-01-15 16:57:00 -08003045 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003046 return None
3047 else:
kelvin8ec71442015-01-15 16:57:00 -08003048 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003049 rawDevices = self.devices()
3050 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003051 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003052 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003053 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3054 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003055 return device
3056 return None
Jon Hallc6793552016-01-19 14:18:37 -08003057 except ( TypeError, ValueError ):
3058 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003059 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003060 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003061 main.log.error( self.name + ": EOF exception found" )
3062 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003063 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003064 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003065 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003066 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003067
You Wang24139872016-05-03 11:48:47 -07003068 def getTopology( self, topologyOutput ):
3069 """
3070 Definition:
3071 Loads a json topology output
3072 Return:
3073 topology = current ONOS topology
3074 """
3075 import json
3076 try:
3077 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003078 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003079 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003080 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003081 except ( TypeError, ValueError ):
3082 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3083 return None
You Wang24139872016-05-03 11:48:47 -07003084 except pexpect.EOF:
3085 main.log.error( self.name + ": EOF exception found" )
3086 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003087 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003088 except Exception:
3089 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003090 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003091
Pier6a0c4de2018-03-18 16:01:30 -07003092 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003093 """
Jon Hallefbd9792015-03-05 16:11:36 -08003094 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003095 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003096 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003097
Flavio Castro82ee2f62016-06-07 15:04:12 -07003098 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003099 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003100 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003101 logLevel = level to log to.
3102 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003103
Jon Hallefbd9792015-03-05 16:11:36 -08003104 Returns: main.TRUE if the number of switches and links are correct,
3105 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003106 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003107 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003108 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003109 try:
You Wang13310252016-07-31 10:56:14 -07003110 summary = self.summary()
3111 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003112 except ( TypeError, ValueError ):
3113 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3114 return main.ERROR
3115 try:
3116 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003117 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003118 return main.ERROR
3119 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003120 # Is the number of switches is what we expected
3121 devices = topology.get( 'devices', False )
3122 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003123 nodes = summary.get( 'nodes', False )
3124 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003125 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003126 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003127 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003128 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003129 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3130 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003131 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003132 output = output + "The number of links and switches match "\
3133 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003134 result = main.TRUE
3135 else:
You Wang24139872016-05-03 11:48:47 -07003136 output = output + \
3137 "The number of links and switches does not match " + \
3138 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003139 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003140 output = output + "\n ONOS sees %i devices" % int( devices )
3141 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003142 if int( numolink ) > 0:
3143 output = output + "and %i links " % int( links )
3144 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003145 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003146 output = output + "and %i controllers " % int( nodes )
3147 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003148 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003149 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003150 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003151 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003152 else:
You Wang24139872016-05-03 11:48:47 -07003153 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003154 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003155 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003156 main.log.error( self.name + ": EOF exception found" )
3157 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003158 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003159 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003160 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003161 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003162
kelvin-onlabd3b64892015-01-20 13:26:24 -08003163 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003164 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003165 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003166 deviceId must be the id of a device as seen in the onos devices command
3167 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003168 role must be either master, standby, or none
3169
Jon Halle3f39ff2015-01-13 11:50:53 -08003170 Returns:
3171 main.TRUE or main.FALSE based on argument verification and
3172 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003173 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003174 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003175 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003176 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003177 cmdStr = "device-role " +\
3178 str( deviceId ) + " " +\
3179 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003180 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003181 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003182 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003183 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003184 if re.search( "Error", handle ):
3185 # end color output to escape any colours
3186 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003187 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003188 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003189 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003190 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003191 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003192 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003193 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003194 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003195 except AssertionError:
3196 main.log.exception( "" )
3197 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003198 except TypeError:
3199 main.log.exception( self.name + ": Object not as expected" )
3200 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003201 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003202 main.log.error( self.name + ": EOF exception found" )
3203 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003204 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003205 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003206 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003207 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003208
kelvin-onlabd3b64892015-01-20 13:26:24 -08003209 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003210 """
Jon Hall0dd09952018-04-19 09:59:11 -07003211 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003212 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003213 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003214 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003215 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003216 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003217 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003218 cmdStr += " -j"
3219 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003220 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003221 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003222 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003223 except AssertionError:
3224 main.log.exception( "" )
3225 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003226 except TypeError:
3227 main.log.exception( self.name + ": Object not as expected" )
3228 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003229 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003230 main.log.error( self.name + ": EOF exception found" )
3231 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003232 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003233 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003234 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003235 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003236
kelvin-onlabd3b64892015-01-20 13:26:24 -08003237 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003238 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003239 CLI command to get the current leader for the Election test application
3240 NOTE: Requires installation of the onos-app-election feature
3241 Returns: Node IP of the leader if one exists
3242 None if none exists
3243 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003244 """
Jon Hall94fd0472014-12-08 11:52:42 -08003245 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003246 cmdStr = "election-test-leader"
3247 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003248 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003249 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003250 # Leader
3251 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003252 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003253 nodeSearch = re.search( leaderPattern, response )
3254 if nodeSearch:
3255 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003256 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003257 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003258 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003259 # no leader
3260 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003261 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003262 nullSearch = re.search( nullPattern, response )
3263 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003264 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003265 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003266 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003267 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003268 main.log.error( "Error in electionTestLeader on " + self.name +
3269 ": " + "unexpected response" )
3270 main.log.error( repr( response ) )
3271 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003272 except AssertionError:
3273 main.log.exception( "" )
3274 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003275 except TypeError:
3276 main.log.exception( self.name + ": Object not as expected" )
3277 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003278 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003279 main.log.error( self.name + ": EOF exception found" )
3280 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003281 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003282 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003283 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003284 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003285
kelvin-onlabd3b64892015-01-20 13:26:24 -08003286 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003287 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003288 CLI command to run for leadership of the Election test application.
3289 NOTE: Requires installation of the onos-app-election feature
3290 Returns: Main.TRUE on success
3291 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003292 """
Jon Hall94fd0472014-12-08 11:52:42 -08003293 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003294 cmdStr = "election-test-run"
3295 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003296 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003297 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003298 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003299 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003300 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003301 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003302 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003303 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003304 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003305 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003306 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003307 main.log.error( "Error in electionTestRun on " + self.name +
3308 ": " + "unexpected response" )
3309 main.log.error( repr( response ) )
3310 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003311 except AssertionError:
3312 main.log.exception( "" )
3313 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003314 except TypeError:
3315 main.log.exception( self.name + ": Object not as expected" )
3316 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003317 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003318 main.log.error( self.name + ": EOF exception found" )
3319 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003320 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003321 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003322 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003323 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003324
kelvin-onlabd3b64892015-01-20 13:26:24 -08003325 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003326 """
Jon Hall94fd0472014-12-08 11:52:42 -08003327 * CLI command to withdraw the local node from leadership election for
3328 * the Election test application.
3329 #NOTE: Requires installation of the onos-app-election feature
3330 Returns: Main.TRUE on success
3331 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003332 """
Jon Hall94fd0472014-12-08 11:52:42 -08003333 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003334 cmdStr = "election-test-withdraw"
3335 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003336 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003337 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003338 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003339 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003340 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003341 if re.search( successPattern, response ):
3342 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003343 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003344 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003345 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003346 main.log.error( "Error in electionTestWithdraw on " +
3347 self.name + ": " + "unexpected response" )
3348 main.log.error( repr( response ) )
3349 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003350 except AssertionError:
3351 main.log.exception( "" )
3352 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003353 except TypeError:
3354 main.log.exception( self.name + ": Object not as expected" )
3355 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003356 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003357 main.log.error( self.name + ": EOF exception found" )
3358 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003359 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003360 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003361 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003362 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003363
kelvin8ec71442015-01-15 16:57:00 -08003364 def getDevicePortsEnabledCount( self, dpid ):
3365 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003366 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003367 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003368 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003369 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003370 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3371 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003372 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003373 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003374 if re.search( "No such device", output ):
3375 main.log.error( "Error in getting ports" )
3376 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003377 return output
Jon Hallc6793552016-01-19 14:18:37 -08003378 except AssertionError:
3379 main.log.exception( "" )
3380 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003381 except TypeError:
3382 main.log.exception( self.name + ": Object not as expected" )
3383 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003384 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003385 main.log.error( self.name + ": EOF exception found" )
3386 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003387 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003388 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003389 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003390 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003391
kelvin8ec71442015-01-15 16:57:00 -08003392 def getDeviceLinksActiveCount( self, dpid ):
3393 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003394 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003395 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003396 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003397 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003398 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3399 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003400 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003401 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003402 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003403 main.log.error( "Error in getting ports " )
3404 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003405 return output
Jon Hallc6793552016-01-19 14:18:37 -08003406 except AssertionError:
3407 main.log.exception( "" )
3408 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003409 except TypeError:
3410 main.log.exception( self.name + ": Object not as expected" )
3411 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003412 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003413 main.log.error( self.name + ": EOF exception found" )
3414 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003415 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003416 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003417 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003418 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003419
kelvin8ec71442015-01-15 16:57:00 -08003420 def getAllIntentIds( self ):
3421 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003422 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003423 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003424 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003425 cmdStr = "onos:intents | grep id="
3426 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003427 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003428 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003429 if re.search( "Error", output ):
3430 main.log.error( "Error in getting ports" )
3431 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003432 return output
Jon Hallc6793552016-01-19 14:18:37 -08003433 except AssertionError:
3434 main.log.exception( "" )
3435 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003436 except TypeError:
3437 main.log.exception( self.name + ": Object not as expected" )
3438 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003439 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003440 main.log.error( self.name + ": EOF exception found" )
3441 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003442 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003443 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003444 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003445 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003446
Jon Hall73509952015-02-24 16:42:56 -08003447 def intentSummary( self ):
3448 """
Jon Hallefbd9792015-03-05 16:11:36 -08003449 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003450 """
3451 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003452 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003453 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003454 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003455 states.append( intent.get( 'state', None ) )
3456 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003457 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003458 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003459 except ( TypeError, ValueError ):
3460 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003461 return None
3462 except pexpect.EOF:
3463 main.log.error( self.name + ": EOF exception found" )
3464 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003465 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003466 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003467 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003468 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003469
Jon Hall61282e32015-03-19 11:34:11 -07003470 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003471 """
3472 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003473 Optional argument:
3474 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003475 """
Jon Hall63604932015-02-26 17:09:50 -08003476 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003477 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003478 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003479 cmdStr += " -j"
3480 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003481 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003482 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003483 return output
Jon Hallc6793552016-01-19 14:18:37 -08003484 except AssertionError:
3485 main.log.exception( "" )
3486 return None
Jon Hall63604932015-02-26 17:09:50 -08003487 except TypeError:
3488 main.log.exception( self.name + ": Object not as expected" )
3489 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003490 except pexpect.EOF:
3491 main.log.error( self.name + ": EOF exception found" )
3492 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003493 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003494 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003495 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003496 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003497
acsmarsa4a4d1e2015-07-10 16:01:24 -07003498 def leaderCandidates( self, jsonFormat=True ):
3499 """
3500 Returns the output of the leaders -c command.
3501 Optional argument:
3502 * jsonFormat - boolean indicating if you want output in json
3503 """
3504 try:
3505 cmdStr = "onos:leaders -c"
3506 if jsonFormat:
3507 cmdStr += " -j"
3508 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003509 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003510 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003511 return output
Jon Hallc6793552016-01-19 14:18:37 -08003512 except AssertionError:
3513 main.log.exception( "" )
3514 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003515 except TypeError:
3516 main.log.exception( self.name + ": Object not as expected" )
3517 return None
3518 except pexpect.EOF:
3519 main.log.error( self.name + ": EOF exception found" )
3520 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003521 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003522 except Exception:
3523 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003524 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003525
Jon Hallc6793552016-01-19 14:18:37 -08003526 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003527 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003528 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003529 topic parameter and an empty list if the topic doesn't exist
3530 If no leader is elected leader in the returned list will be "none"
3531 Returns None if there is a type error processing the json object
3532 """
3533 try:
Jon Hall6e709752016-02-01 13:38:46 -08003534 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003535 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003536 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003537 assert "Command not found:" not in rawOutput, rawOutput
3538 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003539 results = []
3540 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003541 if dict[ "topic" ] == topic:
3542 leader = dict[ "leader" ]
3543 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003544 results.append( leader )
3545 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003546 return results
Jon Hallc6793552016-01-19 14:18:37 -08003547 except AssertionError:
3548 main.log.exception( "" )
3549 return None
3550 except ( TypeError, ValueError ):
3551 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003552 return None
3553 except pexpect.EOF:
3554 main.log.error( self.name + ": EOF exception found" )
3555 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003556 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003557 except Exception:
3558 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003559 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003560
Jon Hall61282e32015-03-19 11:34:11 -07003561 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003562 """
3563 Returns the output of the intent Pending map.
3564 """
Jon Hall63604932015-02-26 17:09:50 -08003565 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003566 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003567 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003568 cmdStr += " -j"
3569 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003570 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003571 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003572 return output
Jon Hallc6793552016-01-19 14:18:37 -08003573 except AssertionError:
3574 main.log.exception( "" )
3575 return None
Jon Hall63604932015-02-26 17:09:50 -08003576 except TypeError:
3577 main.log.exception( self.name + ": Object not as expected" )
3578 return None
3579 except pexpect.EOF:
3580 main.log.error( self.name + ": EOF exception found" )
3581 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003582 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003583 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003584 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003585 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003586
Jon Hall2c8959e2016-12-16 12:17:34 -08003587 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003588 """
3589 Returns the output of the raft partitions command for ONOS.
3590 """
Jon Hall61282e32015-03-19 11:34:11 -07003591 # Sample JSON
3592 # {
3593 # "leader": "tcp://10.128.30.11:7238",
3594 # "members": [
3595 # "tcp://10.128.30.11:7238",
3596 # "tcp://10.128.30.17:7238",
3597 # "tcp://10.128.30.13:7238",
3598 # ],
3599 # "name": "p1",
3600 # "term": 3
3601 # },
Jon Hall63604932015-02-26 17:09:50 -08003602 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003603 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003604 if candidates:
3605 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003606 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003607 cmdStr += " -j"
3608 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003609 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003610 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003611 return output
Jon Hallc6793552016-01-19 14:18:37 -08003612 except AssertionError:
3613 main.log.exception( "" )
3614 return None
Jon Hall63604932015-02-26 17:09:50 -08003615 except TypeError:
3616 main.log.exception( self.name + ": Object not as expected" )
3617 return None
3618 except pexpect.EOF:
3619 main.log.error( self.name + ": EOF exception found" )
3620 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003621 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003622 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003623 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003624 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003625
Jon Halle9f909e2016-09-23 10:43:12 -07003626 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003627 """
3628 Returns the output of the apps command for ONOS. This command lists
3629 information about installed ONOS applications
3630 """
3631 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003632 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003633 # "description":"ONOS OpenFlow protocol southbound providers",
3634 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003635 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003636 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003637 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003638 if summary:
3639 cmdStr += " -s"
3640 if active:
3641 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003642 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003643 cmdStr += " -j"
3644 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003645 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003646 assert "Command not found:" not in output, output
3647 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003648 return output
Jon Hallbe379602015-03-24 13:39:32 -07003649 # FIXME: look at specific exceptions/Errors
3650 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003651 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003652 return None
3653 except TypeError:
3654 main.log.exception( self.name + ": Object not as expected" )
3655 return None
3656 except pexpect.EOF:
3657 main.log.error( self.name + ": EOF exception found" )
3658 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003659 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003660 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003661 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003662 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003663
Jon Hall146f1522015-03-24 15:33:24 -07003664 def appStatus( self, appName ):
3665 """
3666 Uses the onos:apps cli command to return the status of an application.
3667 Returns:
3668 "ACTIVE" - If app is installed and activated
3669 "INSTALLED" - If app is installed and deactivated
3670 "UNINSTALLED" - If app is not installed
3671 None - on error
3672 """
Jon Hall146f1522015-03-24 15:33:24 -07003673 try:
3674 if not isinstance( appName, types.StringType ):
3675 main.log.error( self.name + ".appStatus(): appName must be" +
3676 " a string" )
3677 return None
3678 output = self.apps( jsonFormat=True )
3679 appsJson = json.loads( output )
3680 state = None
3681 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003682 if appName == app.get( 'name' ):
3683 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003684 break
3685 if state == "ACTIVE" or state == "INSTALLED":
3686 return state
3687 elif state is None:
Jon Hall8bafdc02017-09-05 11:36:26 -07003688 main.log.warn( "{} app not found", appName )
Jon Hall146f1522015-03-24 15:33:24 -07003689 return "UNINSTALLED"
3690 elif state:
3691 main.log.error( "Unexpected state from 'onos:apps': " +
3692 str( state ) )
3693 return state
Jon Hallc6793552016-01-19 14:18:37 -08003694 except ( TypeError, ValueError ):
3695 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003696 return None
3697 except pexpect.EOF:
3698 main.log.error( self.name + ": EOF exception found" )
3699 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003700 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003701 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003702 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003703 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003704
Jon Hallbe379602015-03-24 13:39:32 -07003705 def app( self, appName, option ):
3706 """
3707 Interacts with the app command for ONOS. This command manages
3708 application inventory.
3709 """
Jon Hallbe379602015-03-24 13:39:32 -07003710 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003711 # Validate argument types
3712 valid = True
3713 if not isinstance( appName, types.StringType ):
3714 main.log.error( self.name + ".app(): appName must be a " +
3715 "string" )
3716 valid = False
3717 if not isinstance( option, types.StringType ):
3718 main.log.error( self.name + ".app(): option must be a string" )
3719 valid = False
3720 if not valid:
3721 return main.FALSE
3722 # Validate Option
3723 option = option.lower()
3724 # NOTE: Install may become a valid option
3725 if option == "activate":
3726 pass
3727 elif option == "deactivate":
3728 pass
3729 elif option == "uninstall":
3730 pass
3731 else:
3732 # Invalid option
3733 main.log.error( "The ONOS app command argument only takes " +
3734 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003735 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003736 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003737 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003738 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003739 assert output is not None, "Error in sendline"
3740 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003741 if "Error executing command" in output:
3742 main.log.error( "Error in processing onos:app command: " +
3743 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003744 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003745 elif "No such application" in output:
3746 main.log.error( "The application '" + appName +
3747 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003748 return main.FALSE
3749 elif "Command not found:" in output:
3750 main.log.error( "Error in processing onos:app command: " +
3751 str( output ) )
3752 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003753 elif "Unsupported command:" in output:
3754 main.log.error( "Incorrect command given to 'app': " +
3755 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003756 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003757 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003758 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003759 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003760 except AssertionError:
3761 main.log.exception( self.name + ": AssertionError exception found" )
3762 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003763 except TypeError:
3764 main.log.exception( self.name + ": Object not as expected" )
3765 return main.ERROR
3766 except pexpect.EOF:
3767 main.log.error( self.name + ": EOF exception found" )
3768 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003769 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003770 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003771 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003772 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003773
Jon Hallbd16b922015-03-26 17:53:15 -07003774 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003775 """
3776 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003777 appName is the hierarchical app name, not the feature name
3778 If check is True, method will check the status of the app after the
3779 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003780 Returns main.TRUE if the command was successfully sent
3781 main.FALSE if the cli responded with an error or given
3782 incorrect input
3783 """
3784 try:
3785 if not isinstance( appName, types.StringType ):
3786 main.log.error( self.name + ".activateApp(): appName must be" +
3787 " a string" )
3788 return main.FALSE
3789 status = self.appStatus( appName )
3790 if status == "INSTALLED":
3791 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003792 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003793 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003794 status = self.appStatus( appName )
3795 if status == "ACTIVE":
3796 return main.TRUE
3797 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003798 main.log.debug( "The state of application " +
3799 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003800 time.sleep( 1 )
3801 return main.FALSE
3802 else: # not 'check' or command didn't succeed
3803 return response
Jon Hall146f1522015-03-24 15:33:24 -07003804 elif status == "ACTIVE":
3805 return main.TRUE
3806 elif status == "UNINSTALLED":
3807 main.log.error( self.name + ": Tried to activate the " +
3808 "application '" + appName + "' which is not " +
3809 "installed." )
3810 else:
3811 main.log.error( "Unexpected return value from appStatus: " +
3812 str( status ) )
3813 return main.ERROR
3814 except TypeError:
3815 main.log.exception( self.name + ": Object not as expected" )
3816 return main.ERROR
3817 except pexpect.EOF:
3818 main.log.error( self.name + ": EOF exception found" )
3819 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003820 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003821 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003822 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003823 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003824
Jon Hallbd16b922015-03-26 17:53:15 -07003825 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003826 """
3827 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003828 appName is the hierarchical app name, not the feature name
3829 If check is True, method will check the status of the app after the
3830 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003831 Returns main.TRUE if the command was successfully sent
3832 main.FALSE if the cli responded with an error or given
3833 incorrect input
3834 """
3835 try:
3836 if not isinstance( appName, types.StringType ):
3837 main.log.error( self.name + ".deactivateApp(): appName must " +
3838 "be a string" )
3839 return main.FALSE
3840 status = self.appStatus( appName )
3841 if status == "INSTALLED":
3842 return main.TRUE
3843 elif status == "ACTIVE":
3844 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003845 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003846 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003847 status = self.appStatus( appName )
3848 if status == "INSTALLED":
3849 return main.TRUE
3850 else:
3851 time.sleep( 1 )
3852 return main.FALSE
3853 else: # not check or command didn't succeed
3854 return response
Jon Hall146f1522015-03-24 15:33:24 -07003855 elif status == "UNINSTALLED":
3856 main.log.warn( self.name + ": Tried to deactivate the " +
3857 "application '" + appName + "' which is not " +
3858 "installed." )
3859 return main.TRUE
3860 else:
3861 main.log.error( "Unexpected return value from appStatus: " +
3862 str( status ) )
3863 return main.ERROR
3864 except TypeError:
3865 main.log.exception( self.name + ": Object not as expected" )
3866 return main.ERROR
3867 except pexpect.EOF:
3868 main.log.error( self.name + ": EOF exception found" )
3869 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003870 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003871 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003872 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003873 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003874
Jon Hallbd16b922015-03-26 17:53:15 -07003875 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003876 """
3877 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003878 appName is the hierarchical app name, not the feature name
3879 If check is True, method will check the status of the app after the
3880 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003881 Returns main.TRUE if the command was successfully sent
3882 main.FALSE if the cli responded with an error or given
3883 incorrect input
3884 """
3885 # TODO: check with Thomas about the state machine for apps
3886 try:
3887 if not isinstance( appName, types.StringType ):
3888 main.log.error( self.name + ".uninstallApp(): appName must " +
3889 "be a string" )
3890 return main.FALSE
3891 status = self.appStatus( appName )
3892 if status == "INSTALLED":
3893 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003894 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003895 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003896 status = self.appStatus( appName )
3897 if status == "UNINSTALLED":
3898 return main.TRUE
3899 else:
3900 time.sleep( 1 )
3901 return main.FALSE
3902 else: # not check or command didn't succeed
3903 return response
Jon Hall146f1522015-03-24 15:33:24 -07003904 elif status == "ACTIVE":
3905 main.log.warn( self.name + ": Tried to uninstall the " +
3906 "application '" + appName + "' which is " +
3907 "currently active." )
3908 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003909 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003910 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003911 status = self.appStatus( appName )
3912 if status == "UNINSTALLED":
3913 return main.TRUE
3914 else:
3915 time.sleep( 1 )
3916 return main.FALSE
3917 else: # not check or command didn't succeed
3918 return response
Jon Hall146f1522015-03-24 15:33:24 -07003919 elif status == "UNINSTALLED":
3920 return main.TRUE
3921 else:
3922 main.log.error( "Unexpected return value from appStatus: " +
3923 str( status ) )
3924 return main.ERROR
3925 except TypeError:
3926 main.log.exception( self.name + ": Object not as expected" )
3927 return main.ERROR
3928 except pexpect.EOF:
3929 main.log.error( self.name + ": EOF exception found" )
3930 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003931 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003932 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003933 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003934 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003935
3936 def appIDs( self, jsonFormat=True ):
3937 """
3938 Show the mappings between app id and app names given by the 'app-ids'
3939 cli command
3940 """
3941 try:
3942 cmdStr = "app-ids"
3943 if jsonFormat:
3944 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003945 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003946 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003947 assert "Command not found:" not in output, output
3948 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003949 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003950 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003951 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003952 return None
3953 except TypeError:
3954 main.log.exception( self.name + ": Object not as expected" )
3955 return None
3956 except pexpect.EOF:
3957 main.log.error( self.name + ": EOF exception found" )
3958 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003959 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003960 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003961 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003962 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003963
3964 def appToIDCheck( self ):
3965 """
3966 This method will check that each application's ID listed in 'apps' is
3967 the same as the ID listed in 'app-ids'. The check will also check that
3968 there are no duplicate IDs issued. Note that an app ID should be
3969 a globaly unique numerical identifier for app/app-like features. Once
3970 an ID is registered, the ID is never freed up so that if an app is
3971 reinstalled it will have the same ID.
3972
3973 Returns: main.TRUE if the check passes and
3974 main.FALSE if the check fails or
3975 main.ERROR if there is some error in processing the test
3976 """
3977 try:
Jon Hall390696c2015-05-05 17:13:41 -07003978 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003979 rawJson = self.appIDs( jsonFormat=True )
3980 if rawJson:
3981 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003982 else:
Jon Hallc6793552016-01-19 14:18:37 -08003983 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003984 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003985 rawJson = self.apps( jsonFormat=True )
3986 if rawJson:
3987 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003988 else:
Jon Hallc6793552016-01-19 14:18:37 -08003989 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003990 bail = True
3991 if bail:
3992 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003993 result = main.TRUE
3994 for app in apps:
3995 appID = app.get( 'id' )
3996 if appID is None:
3997 main.log.error( "Error parsing app: " + str( app ) )
3998 result = main.FALSE
3999 appName = app.get( 'name' )
4000 if appName is None:
4001 main.log.error( "Error parsing app: " + str( app ) )
4002 result = main.FALSE
4003 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004004 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004005 if not current: # if ids doesn't have this id
4006 result = main.FALSE
4007 main.log.error( "'app-ids' does not have the ID for " +
4008 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004009 main.log.debug( "apps command returned: " + str( app ) +
4010 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004011 elif len( current ) > 1:
4012 # there is more than one app with this ID
4013 result = main.FALSE
4014 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004015 elif not current[ 0 ][ 'name' ] == appName:
4016 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004017 result = main.FALSE
4018 main.log.error( "'app-ids' has " + str( currentName ) +
4019 " registered under id:" + str( appID ) +
4020 " but 'apps' has " + str( appName ) )
4021 else:
4022 pass # id and name match!
4023 # now make sure that app-ids has no duplicates
4024 idsList = []
4025 namesList = []
4026 for item in ids:
4027 idsList.append( item[ 'id' ] )
4028 namesList.append( item[ 'name' ] )
4029 if len( idsList ) != len( set( idsList ) ) or\
4030 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004031 main.log.error( "'app-ids' has some duplicate entries: \n"
4032 + json.dumps( ids,
4033 sort_keys=True,
4034 indent=4,
4035 separators=( ',', ': ' ) ) )
4036 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004037 return result
Jon Hallc6793552016-01-19 14:18:37 -08004038 except ( TypeError, ValueError ):
4039 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004040 return main.ERROR
4041 except pexpect.EOF:
4042 main.log.error( self.name + ": EOF exception found" )
4043 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004044 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004045 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004046 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004047 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004048
Jon Hallfb760a02015-04-13 15:35:03 -07004049 def getCfg( self, component=None, propName=None, short=False,
4050 jsonFormat=True ):
4051 """
4052 Get configuration settings from onos cli
4053 Optional arguments:
4054 component - Optionally only list configurations for a specific
4055 component. If None, all components with configurations
4056 are displayed. Case Sensitive string.
4057 propName - If component is specified, propName option will show
4058 only this specific configuration from that component.
4059 Case Sensitive string.
4060 jsonFormat - Returns output as json. Note that this will override
4061 the short option
4062 short - Short, less verbose, version of configurations.
4063 This is overridden by the json option
4064 returns:
4065 Output from cli as a string or None on error
4066 """
4067 try:
4068 baseStr = "cfg"
4069 cmdStr = " get"
4070 componentStr = ""
4071 if component:
4072 componentStr += " " + component
4073 if propName:
4074 componentStr += " " + propName
4075 if jsonFormat:
4076 baseStr += " -j"
4077 elif short:
4078 baseStr += " -s"
4079 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004080 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004081 assert "Command not found:" not in output, output
4082 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004083 return output
4084 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004085 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004086 return None
4087 except TypeError:
4088 main.log.exception( self.name + ": Object not as expected" )
4089 return None
4090 except pexpect.EOF:
4091 main.log.error( self.name + ": EOF exception found" )
4092 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004093 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004094 except Exception:
4095 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004096 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004097
4098 def setCfg( self, component, propName, value=None, check=True ):
4099 """
4100 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004101 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004102 component - The case sensitive name of the component whose
4103 property is to be set
4104 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004105 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004106 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004107 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004108 check - Boolean, Check whether the option was successfully set this
4109 only applies when a value is given.
4110 returns:
4111 main.TRUE on success or main.FALSE on failure. If check is False,
4112 will return main.TRUE unless there is an error
4113 """
4114 try:
4115 baseStr = "cfg"
4116 cmdStr = " set " + str( component ) + " " + str( propName )
4117 if value is not None:
4118 cmdStr += " " + str( value )
4119 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004120 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004121 assert "Command not found:" not in output, output
4122 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004123 if value and check:
4124 results = self.getCfg( component=str( component ),
4125 propName=str( propName ),
4126 jsonFormat=True )
4127 # Check if current value is what we just set
4128 try:
4129 jsonOutput = json.loads( results )
4130 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004131 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004132 main.log.exception( "Error parsing cfg output" )
4133 main.log.error( "output:" + repr( results ) )
4134 return main.FALSE
4135 if current == str( value ):
4136 return main.TRUE
4137 return main.FALSE
4138 return main.TRUE
4139 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004140 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004141 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004142 except ( TypeError, ValueError ):
4143 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004144 return main.FALSE
4145 except pexpect.EOF:
4146 main.log.error( self.name + ": EOF exception found" )
4147 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004148 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004149 except Exception:
4150 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004151 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004152
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004153 def distPrimitivesSend( self, cmd ):
4154 """
4155 Function to handle sending cli commands for the distributed primitives test app
4156
4157 This command will catch some exceptions and retry the command on some
4158 specific store exceptions.
4159
4160 Required arguments:
4161 cmd - The command to send to the cli
4162 returns:
4163 string containing the cli output
4164 None on Error
4165 """
4166 try:
4167 output = self.sendline( cmd )
4168 try:
4169 assert output is not None, "Error in sendline"
4170 # TODO: Maybe make this less hardcoded
4171 # ConsistentMap Exceptions
4172 assert "org.onosproject.store.service" not in output
4173 # Node not leader
4174 assert "java.lang.IllegalStateException" not in output
4175 except AssertionError:
4176 main.log.error( "Error in processing '" + cmd + "' " +
4177 "command: " + str( output ) )
4178 retryTime = 30 # Conservative time, given by Madan
4179 main.log.info( "Waiting " + str( retryTime ) +
4180 "seconds before retrying." )
4181 time.sleep( retryTime ) # Due to change in mastership
4182 output = self.sendline( cmd )
4183 assert output is not None, "Error in sendline"
4184 assert "Command not found:" not in output, output
4185 assert "Error executing command" not in output, output
4186 main.log.info( self.name + ": " + output )
4187 return output
4188 except AssertionError:
4189 main.log.exception( "Error in processing '" + cmd + "' command." )
4190 return None
4191 except TypeError:
4192 main.log.exception( self.name + ": Object not as expected" )
4193 return None
4194 except pexpect.EOF:
4195 main.log.error( self.name + ": EOF exception found" )
4196 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004197 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004198 except Exception:
4199 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004200 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004201
Jon Hall390696c2015-05-05 17:13:41 -07004202 def setTestAdd( self, setName, values ):
4203 """
4204 CLI command to add elements to a distributed set.
4205 Arguments:
4206 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004207 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004208 Example usages:
4209 setTestAdd( "set1", "a b c" )
4210 setTestAdd( "set2", "1" )
4211 returns:
4212 main.TRUE on success OR
4213 main.FALSE if elements were already in the set OR
4214 main.ERROR on error
4215 """
4216 try:
4217 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004218 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004219 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4220 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004221 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004222 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004223 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004224 return main.FALSE
4225 else:
4226 main.log.error( self.name + ": setTestAdd did not" +
4227 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004228 main.log.debug( self.name + " actual: " + repr( output ) )
4229 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004230 except TypeError:
4231 main.log.exception( self.name + ": Object not as expected" )
4232 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004233 except Exception:
4234 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004235 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004236
4237 def setTestRemove( self, setName, values, clear=False, retain=False ):
4238 """
4239 CLI command to remove elements from a distributed set.
4240 Required arguments:
4241 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004242 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004243 Optional arguments:
4244 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004245 retain - Retain only the given values. (intersection of the
4246 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004247 returns:
4248 main.TRUE on success OR
4249 main.FALSE if the set was not changed OR
4250 main.ERROR on error
4251 """
4252 try:
4253 cmdStr = "set-test-remove "
4254 if clear:
4255 cmdStr += "-c " + str( setName )
4256 elif retain:
4257 cmdStr += "-r " + str( setName ) + " " + str( values )
4258 else:
4259 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004260 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004261 if clear:
4262 pattern = "Set " + str( setName ) + " cleared"
4263 if re.search( pattern, output ):
4264 return main.TRUE
4265 elif retain:
4266 positivePattern = str( setName ) + " was pruned to contain " +\
4267 "only elements of set \[(.*)\]"
4268 negativePattern = str( setName ) + " was not changed by " +\
4269 "retaining only elements of the set " +\
4270 "\[(.*)\]"
4271 if re.search( positivePattern, output ):
4272 return main.TRUE
4273 elif re.search( negativePattern, output ):
4274 return main.FALSE
4275 else:
4276 positivePattern = "\[(.*)\] was removed from the set " +\
4277 str( setName )
4278 if ( len( values.split() ) == 1 ):
4279 negativePattern = "\[(.*)\] was not in set " +\
4280 str( setName )
4281 else:
4282 negativePattern = "No element of \[(.*)\] was in set " +\
4283 str( setName )
4284 if re.search( positivePattern, output ):
4285 return main.TRUE
4286 elif re.search( negativePattern, output ):
4287 return main.FALSE
4288 main.log.error( self.name + ": setTestRemove did not" +
4289 " match expected output" )
4290 main.log.debug( self.name + " expected: " + pattern )
4291 main.log.debug( self.name + " actual: " + repr( output ) )
4292 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004293 except TypeError:
4294 main.log.exception( self.name + ": Object not as expected" )
4295 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004296 except Exception:
4297 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004298 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004299
4300 def setTestGet( self, setName, values="" ):
4301 """
4302 CLI command to get the elements in a distributed set.
4303 Required arguments:
4304 setName - The name of the set to remove from.
4305 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004306 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004307 returns:
4308 main.ERROR on error OR
4309 A list of elements in the set if no optional arguments are
4310 supplied OR
4311 A tuple containing the list then:
4312 main.FALSE if the given values are not in the set OR
4313 main.TRUE if the given values are in the set OR
4314 """
4315 try:
4316 values = str( values ).strip()
4317 setName = str( setName ).strip()
4318 length = len( values.split() )
4319 containsCheck = None
4320 # Patterns to match
4321 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004322 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004323 containsTrue = "Set " + setName + " contains the value " + values
4324 containsFalse = "Set " + setName + " did not contain the value " +\
4325 values
4326 containsAllTrue = "Set " + setName + " contains the the subset " +\
4327 setPattern
4328 containsAllFalse = "Set " + setName + " did not contain the the" +\
4329 " subset " + setPattern
4330
4331 cmdStr = "set-test-get "
4332 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004333 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004334 if length == 0:
4335 match = re.search( pattern, output )
4336 else: # if given values
4337 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004338 patternTrue = pattern + "\r\n" + containsTrue
4339 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004340 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004341 patternTrue = pattern + "\r\n" + containsAllTrue
4342 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004343 matchTrue = re.search( patternTrue, output )
4344 matchFalse = re.search( patternFalse, output )
4345 if matchTrue:
4346 containsCheck = main.TRUE
4347 match = matchTrue
4348 elif matchFalse:
4349 containsCheck = main.FALSE
4350 match = matchFalse
4351 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004352 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004353 "expected output" )
4354 main.log.debug( self.name + " expected: " + pattern )
4355 main.log.debug( self.name + " actual: " + repr( output ) )
4356 match = None
4357 if match:
4358 setMatch = match.group( 1 )
4359 if setMatch == '':
4360 setList = []
4361 else:
4362 setList = setMatch.split( ", " )
4363 if length > 0:
4364 return ( setList, containsCheck )
4365 else:
4366 return setList
4367 else: # no match
4368 main.log.error( self.name + ": setTestGet did not" +
4369 " match expected output" )
4370 main.log.debug( self.name + " expected: " + pattern )
4371 main.log.debug( self.name + " actual: " + repr( output ) )
4372 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004373 except TypeError:
4374 main.log.exception( self.name + ": Object not as expected" )
4375 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004376 except Exception:
4377 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004378 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004379
4380 def setTestSize( self, setName ):
4381 """
4382 CLI command to get the elements in a distributed set.
4383 Required arguments:
4384 setName - The name of the set to remove from.
4385 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004386 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004387 None on error
4388 """
4389 try:
4390 # TODO: Should this check against the number of elements returned
4391 # and then return true/false based on that?
4392 setName = str( setName ).strip()
4393 # Patterns to match
4394 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004395 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004396 setPattern
4397 cmdStr = "set-test-get -s "
4398 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004399 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004400 match = re.search( pattern, output )
4401 if match:
4402 setSize = int( match.group( 1 ) )
4403 setMatch = match.group( 2 )
4404 if len( setMatch.split() ) == setSize:
4405 main.log.info( "The size returned by " + self.name +
4406 " matches the number of elements in " +
4407 "the returned set" )
4408 else:
4409 main.log.error( "The size returned by " + self.name +
4410 " does not match the number of " +
4411 "elements in the returned set." )
4412 return setSize
4413 else: # no match
4414 main.log.error( self.name + ": setTestGet did not" +
4415 " match expected output" )
4416 main.log.debug( self.name + " expected: " + pattern )
4417 main.log.debug( self.name + " actual: " + repr( output ) )
4418 return None
Jon Hall390696c2015-05-05 17:13:41 -07004419 except TypeError:
4420 main.log.exception( self.name + ": Object not as expected" )
4421 return None
Jon Hall390696c2015-05-05 17:13:41 -07004422 except Exception:
4423 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004424 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004425
Jon Hall80daded2015-05-27 16:07:00 -07004426 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004427 """
4428 Command to list the various counters in the system.
4429 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004430 if jsonFormat, a string of the json object returned by the cli
4431 command
4432 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004433 None on error
4434 """
Jon Hall390696c2015-05-05 17:13:41 -07004435 try:
Jon Hall390696c2015-05-05 17:13:41 -07004436 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004437 if jsonFormat:
4438 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004439 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004440 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004441 assert "Command not found:" not in output, output
4442 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004443 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004444 return output
Jon Hall390696c2015-05-05 17:13:41 -07004445 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004446 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004447 return None
Jon Hall390696c2015-05-05 17:13:41 -07004448 except TypeError:
4449 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004450 return None
Jon Hall390696c2015-05-05 17:13:41 -07004451 except pexpect.EOF:
4452 main.log.error( self.name + ": EOF exception found" )
4453 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004454 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004455 except Exception:
4456 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004457 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004458
Jon Hall935db192016-04-19 00:22:04 -07004459 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004460 """
Jon Halle1a3b752015-07-22 13:02:46 -07004461 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004462 Required arguments:
4463 counter - The name of the counter to increment.
4464 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004465 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004466 returns:
4467 integer value of the counter or
4468 None on Error
4469 """
4470 try:
4471 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004472 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004473 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004474 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004475 if delta != 1:
4476 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004477 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004478 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004479 match = re.search( pattern, output )
4480 if match:
4481 return int( match.group( 1 ) )
4482 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004483 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004484 " match expected output." )
4485 main.log.debug( self.name + " expected: " + pattern )
4486 main.log.debug( self.name + " actual: " + repr( output ) )
4487 return None
Jon Hall390696c2015-05-05 17:13:41 -07004488 except TypeError:
4489 main.log.exception( self.name + ": Object not as expected" )
4490 return None
Jon Hall390696c2015-05-05 17:13:41 -07004491 except Exception:
4492 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004493 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004494
Jon Hall935db192016-04-19 00:22:04 -07004495 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004496 """
4497 CLI command to get a distributed counter then add a delta to it.
4498 Required arguments:
4499 counter - The name of the counter to increment.
4500 Optional arguments:
4501 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004502 returns:
4503 integer value of the counter or
4504 None on Error
4505 """
4506 try:
4507 counter = str( counter )
4508 delta = int( delta )
4509 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004510 cmdStr += counter
4511 if delta != 1:
4512 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004513 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004514 pattern = counter + " was updated to (-?\d+)"
4515 match = re.search( pattern, output )
4516 if match:
4517 return int( match.group( 1 ) )
4518 else:
4519 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4520 " match expected output." )
4521 main.log.debug( self.name + " expected: " + pattern )
4522 main.log.debug( self.name + " actual: " + repr( output ) )
4523 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004524 except TypeError:
4525 main.log.exception( self.name + ": Object not as expected" )
4526 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004527 except Exception:
4528 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004529 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004530
4531 def valueTestGet( self, valueName ):
4532 """
4533 CLI command to get the value of an atomic value.
4534 Required arguments:
4535 valueName - The name of the value to get.
4536 returns:
4537 string value of the value or
4538 None on Error
4539 """
4540 try:
4541 valueName = str( valueName )
4542 cmdStr = "value-test "
4543 operation = "get"
4544 cmdStr = "value-test {} {}".format( valueName,
4545 operation )
4546 output = self.distPrimitivesSend( cmdStr )
4547 pattern = "(\w+)"
4548 match = re.search( pattern, output )
4549 if match:
4550 return match.group( 1 )
4551 else:
4552 main.log.error( self.name + ": valueTestGet did not" +
4553 " match expected output." )
4554 main.log.debug( self.name + " expected: " + pattern )
4555 main.log.debug( self.name + " actual: " + repr( output ) )
4556 return None
4557 except TypeError:
4558 main.log.exception( self.name + ": Object not as expected" )
4559 return None
4560 except Exception:
4561 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004562 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004563
4564 def valueTestSet( self, valueName, newValue ):
4565 """
4566 CLI command to set the value of an atomic value.
4567 Required arguments:
4568 valueName - The name of the value to set.
4569 newValue - The value to assign to the given value.
4570 returns:
4571 main.TRUE on success or
4572 main.ERROR on Error
4573 """
4574 try:
4575 valueName = str( valueName )
4576 newValue = str( newValue )
4577 operation = "set"
4578 cmdStr = "value-test {} {} {}".format( valueName,
4579 operation,
4580 newValue )
4581 output = self.distPrimitivesSend( cmdStr )
4582 if output is not None:
4583 return main.TRUE
4584 else:
4585 return main.ERROR
4586 except TypeError:
4587 main.log.exception( self.name + ": Object not as expected" )
4588 return main.ERROR
4589 except Exception:
4590 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004591 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004592
4593 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4594 """
4595 CLI command to compareAndSet the value of an atomic value.
4596 Required arguments:
4597 valueName - The name of the value.
4598 oldValue - Compare the current value of the atomic value to this
4599 newValue - If the value equals oldValue, set the value to newValue
4600 returns:
4601 main.TRUE on success or
4602 main.FALSE on failure or
4603 main.ERROR on Error
4604 """
4605 try:
4606 valueName = str( valueName )
4607 oldValue = str( oldValue )
4608 newValue = str( newValue )
4609 operation = "compareAndSet"
4610 cmdStr = "value-test {} {} {} {}".format( valueName,
4611 operation,
4612 oldValue,
4613 newValue )
4614 output = self.distPrimitivesSend( cmdStr )
4615 pattern = "(\w+)"
4616 match = re.search( pattern, output )
4617 if match:
4618 result = match.group( 1 )
4619 if result == "true":
4620 return main.TRUE
4621 elif result == "false":
4622 return main.FALSE
4623 else:
4624 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4625 " match expected output." )
4626 main.log.debug( self.name + " expected: " + pattern )
4627 main.log.debug( self.name + " actual: " + repr( output ) )
4628 return main.ERROR
4629 except TypeError:
4630 main.log.exception( self.name + ": Object not as expected" )
4631 return main.ERROR
4632 except Exception:
4633 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004634 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004635
4636 def valueTestGetAndSet( self, valueName, newValue ):
4637 """
4638 CLI command to getAndSet the value of an atomic value.
4639 Required arguments:
4640 valueName - The name of the value to get.
4641 newValue - The value to assign to the given value
4642 returns:
4643 string value of the value or
4644 None on Error
4645 """
4646 try:
4647 valueName = str( valueName )
4648 cmdStr = "value-test "
4649 operation = "getAndSet"
4650 cmdStr += valueName + " " + operation
4651 cmdStr = "value-test {} {} {}".format( valueName,
4652 operation,
4653 newValue )
4654 output = self.distPrimitivesSend( cmdStr )
4655 pattern = "(\w+)"
4656 match = re.search( pattern, output )
4657 if match:
4658 return match.group( 1 )
4659 else:
4660 main.log.error( self.name + ": valueTestGetAndSet did not" +
4661 " match expected output." )
4662 main.log.debug( self.name + " expected: " + pattern )
4663 main.log.debug( self.name + " actual: " + repr( output ) )
4664 return None
4665 except TypeError:
4666 main.log.exception( self.name + ": Object not as expected" )
4667 return None
4668 except Exception:
4669 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004670 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004671
4672 def valueTestDestroy( self, valueName ):
4673 """
4674 CLI command to destroy an atomic value.
4675 Required arguments:
4676 valueName - The name of the value to destroy.
4677 returns:
4678 main.TRUE on success or
4679 main.ERROR on Error
4680 """
4681 try:
4682 valueName = str( valueName )
4683 cmdStr = "value-test "
4684 operation = "destroy"
4685 cmdStr += valueName + " " + operation
4686 output = self.distPrimitivesSend( cmdStr )
4687 if output is not None:
4688 return main.TRUE
4689 else:
4690 return main.ERROR
4691 except TypeError:
4692 main.log.exception( self.name + ": Object not as expected" )
4693 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004694 except Exception:
4695 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004696 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004697
YPZhangfebf7302016-05-24 16:45:56 -07004698 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004699 """
4700 Description: Execute summary command in onos
4701 Returns: json object ( summary -j ), returns main.FALSE if there is
4702 no output
4703
4704 """
4705 try:
4706 cmdStr = "summary"
4707 if jsonFormat:
4708 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004709 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004710 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004711 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004712 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004713 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004714 if not handle:
4715 main.log.error( self.name + ": There is no output in " +
4716 "summary command" )
4717 return main.FALSE
4718 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004719 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004720 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004721 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004722 except TypeError:
4723 main.log.exception( self.name + ": Object not as expected" )
4724 return None
4725 except pexpect.EOF:
4726 main.log.error( self.name + ": EOF exception found" )
4727 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004728 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004729 except Exception:
4730 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004731 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004732
Jon Hall935db192016-04-19 00:22:04 -07004733 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004734 """
4735 CLI command to get the value of a key in a consistent map using
4736 transactions. This a test function and can only get keys from the
4737 test map hard coded into the cli command
4738 Required arguments:
4739 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004740 returns:
4741 The string value of the key or
4742 None on Error
4743 """
4744 try:
4745 keyName = str( keyName )
4746 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004747 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004748 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004749 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4750 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004751 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004752 return None
4753 else:
4754 match = re.search( pattern, output )
4755 if match:
4756 return match.groupdict()[ 'value' ]
4757 else:
4758 main.log.error( self.name + ": transactionlMapGet did not" +
4759 " match expected output." )
4760 main.log.debug( self.name + " expected: " + pattern )
4761 main.log.debug( self.name + " actual: " + repr( output ) )
4762 return None
4763 except TypeError:
4764 main.log.exception( self.name + ": Object not as expected" )
4765 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004766 except Exception:
4767 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004768 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004769
Jon Hall935db192016-04-19 00:22:04 -07004770 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004771 """
4772 CLI command to put a value into 'numKeys' number of keys in a
4773 consistent map using transactions. This a test function and can only
4774 put into keys named 'Key#' of the test map hard coded into the cli command
4775 Required arguments:
4776 numKeys - Number of keys to add the value to
4777 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004778 returns:
4779 A dictionary whose keys are the name of the keys put into the map
4780 and the values of the keys are dictionaries whose key-values are
4781 'value': value put into map and optionaly
4782 'oldValue': Previous value in the key or
4783 None on Error
4784
4785 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004786 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4787 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004788 """
4789 try:
4790 numKeys = str( numKeys )
4791 value = str( value )
4792 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004793 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004794 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004795 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4796 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4797 results = {}
4798 for line in output.splitlines():
4799 new = re.search( newPattern, line )
4800 updated = re.search( updatedPattern, line )
4801 if new:
4802 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4803 elif updated:
4804 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004805 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004806 else:
4807 main.log.error( self.name + ": transactionlMapGet did not" +
4808 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004809 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4810 newPattern,
4811 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004812 main.log.debug( self.name + " actual: " + repr( output ) )
4813 return results
4814 except TypeError:
4815 main.log.exception( self.name + ": Object not as expected" )
4816 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004817 except Exception:
4818 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004819 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004820
acsmarsdaea66c2015-09-03 11:44:06 -07004821 def maps( self, jsonFormat=True ):
4822 """
4823 Description: Returns result of onos:maps
4824 Optional:
4825 * jsonFormat: enable json formatting of output
4826 """
4827 try:
4828 cmdStr = "maps"
4829 if jsonFormat:
4830 cmdStr += " -j"
4831 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004832 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004833 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004834 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004835 except AssertionError:
4836 main.log.exception( "" )
4837 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004838 except TypeError:
4839 main.log.exception( self.name + ": Object not as expected" )
4840 return None
4841 except pexpect.EOF:
4842 main.log.error( self.name + ": EOF exception found" )
4843 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004844 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004845 except Exception:
4846 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004847 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004848
4849 def getSwController( self, uri, jsonFormat=True ):
4850 """
4851 Descrition: Gets the controller information from the device
4852 """
4853 try:
4854 cmd = "device-controllers "
4855 if jsonFormat:
4856 cmd += "-j "
4857 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004858 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004859 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004860 return response
Jon Hallc6793552016-01-19 14:18:37 -08004861 except AssertionError:
4862 main.log.exception( "" )
4863 return None
GlennRC050596c2015-11-18 17:06:41 -08004864 except TypeError:
4865 main.log.exception( self.name + ": Object not as expected" )
4866 return None
4867 except pexpect.EOF:
4868 main.log.error( self.name + ": EOF exception found" )
4869 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004870 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004871 except Exception:
4872 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004873 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004874
4875 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4876 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004877 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004878
4879 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004880 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08004881 ip - String or List: The ip address of the controller.
4882 This parameter can be formed in a couple of different ways.
4883 VALID:
4884 10.0.0.1 - just the ip address
4885 tcp:10.0.0.1 - the protocol and the ip address
4886 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4887 so that you can add controllers with different
4888 protocols and ports
4889 INVALID:
4890 10.0.0.1:6653 - this is not supported by ONOS
4891
4892 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4893 port - The port number.
4894 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4895
4896 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4897 """
4898 try:
4899 cmd = "device-setcontrollers"
4900
4901 if jsonFormat:
4902 cmd += " -j"
4903 cmd += " " + uri
4904 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004905 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08004906 for item in ip:
4907 if ":" in item:
4908 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004909 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08004910 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004911 elif "." in sitem[ 1 ]:
4912 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08004913 else:
4914 main.log.error( "Malformed entry: " + item )
4915 raise TypeError
4916 else:
4917 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004918 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004919 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004920 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004921 if "Error" in response:
4922 main.log.error( response )
4923 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004924 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004925 except AssertionError:
4926 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004927 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004928 except TypeError:
4929 main.log.exception( self.name + ": Object not as expected" )
4930 return main.FALSE
4931 except pexpect.EOF:
4932 main.log.error( self.name + ": EOF exception found" )
4933 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004934 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004935 except Exception:
4936 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004937 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004938
4939 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004940 '''
GlennRC20fc6522015-12-23 23:26:57 -08004941 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004942 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08004943 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004944 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08004945 Returns:
4946 Returns main.FALSE if an exception is thrown or an error is present
4947 in the response. Otherwise, returns main.TRUE.
4948 NOTE:
4949 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004950 '''
GlennRC20fc6522015-12-23 23:26:57 -08004951 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004952 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07004953 deviceStr = device
4954 device = []
4955 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004956
4957 for d in device:
4958 time.sleep( 1 )
4959 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004960 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004961 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004962 if "Error" in response:
4963 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4964 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004965 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004966 except AssertionError:
4967 main.log.exception( "" )
4968 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004969 except TypeError:
4970 main.log.exception( self.name + ": Object not as expected" )
4971 return main.FALSE
4972 except pexpect.EOF:
4973 main.log.error( self.name + ": EOF exception found" )
4974 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004975 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004976 except Exception:
4977 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004978 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004979
4980 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004981 '''
GlennRC20fc6522015-12-23 23:26:57 -08004982 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004983 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08004984 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004985 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08004986 Returns:
4987 Returns main.FALSE if an exception is thrown or an error is present
4988 in the response. Otherwise, returns main.TRUE.
4989 NOTE:
4990 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004991 '''
GlennRC20fc6522015-12-23 23:26:57 -08004992 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004993 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08004994 host = list( host )
4995
4996 for h in host:
4997 time.sleep( 1 )
4998 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004999 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005000 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005001 if "Error" in response:
5002 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5003 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005004 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005005 except AssertionError:
5006 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005007 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005008 except TypeError:
5009 main.log.exception( self.name + ": Object not as expected" )
5010 return main.FALSE
5011 except pexpect.EOF:
5012 main.log.error( self.name + ": EOF exception found" )
5013 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005014 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005015 except Exception:
5016 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005017 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005018
YPZhangfebf7302016-05-24 16:45:56 -07005019 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005020 '''
GlennRCed771242016-01-13 17:02:47 -08005021 Description:
5022 Bring link down or up in the null-provider.
5023 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005024 begin - (string) One end of a device or switch.
5025 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005026 returns:
5027 main.TRUE if no exceptions were thrown and no Errors are
5028 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005029 '''
GlennRCed771242016-01-13 17:02:47 -08005030 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005031 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005032 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005033 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005034 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005035 if "Error" in response or "Failure" in response:
5036 main.log.error( response )
5037 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005038 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005039 except AssertionError:
5040 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005041 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005042 except TypeError:
5043 main.log.exception( self.name + ": Object not as expected" )
5044 return main.FALSE
5045 except pexpect.EOF:
5046 main.log.error( self.name + ": EOF exception found" )
5047 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005048 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005049 except Exception:
5050 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005051 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005052
Jon Hall2c8959e2016-12-16 12:17:34 -08005053 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005054 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005055 Description:
5056 Changes the state of port in an OF switch by means of the
5057 PORTSTATUS OF messages.
5058 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005059 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5060 port - (string) target port in the device. Ex: '2'
5061 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005062 returns:
5063 main.TRUE if no exceptions were thrown and no Errors are
5064 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005065 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005066 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005067 state = state.lower()
5068 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005069 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005070 response = self.sendline( cmd, showResponse=True )
5071 assert response is not None, "Error in sendline"
5072 assert "Command not found:" not in response, response
5073 if "Error" in response or "Failure" in response:
5074 main.log.error( response )
5075 return main.FALSE
5076 return main.TRUE
5077 except AssertionError:
5078 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005079 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005080 except TypeError:
5081 main.log.exception( self.name + ": Object not as expected" )
5082 return main.FALSE
5083 except pexpect.EOF:
5084 main.log.error( self.name + ": EOF exception found" )
5085 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005086 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005087 except Exception:
5088 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005089 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005090
5091 def logSet( self, level="INFO", app="org.onosproject" ):
5092 """
5093 Set the logging level to lvl for a specific app
5094 returns main.TRUE on success
5095 returns main.FALSE if Error occurred
5096 if noExit is True, TestON will not exit, but clean up
5097 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5098 Level defaults to INFO
5099 """
5100 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005101 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005102 self.handle.expect( "onos>" )
5103
5104 response = self.handle.before
5105 if re.search( "Error", response ):
5106 return main.FALSE
5107 return main.TRUE
5108 except pexpect.TIMEOUT:
5109 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005110 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005111 except pexpect.EOF:
5112 main.log.error( self.name + ": EOF exception found" )
5113 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005114 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005115 except Exception:
5116 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005117 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005118
5119 def getGraphDict( self, timeout=60, includeHost=False ):
5120 """
5121 Return a dictionary which describes the latest network topology data as a
5122 graph.
5123 An example of the dictionary:
5124 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5125 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5126 Each vertex should at least have an 'edges' attribute which describes the
5127 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005128 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005129 list of attributes.
5130 An example of the edges dictionary:
5131 'edges': { vertex2: { 'port': ..., 'weight': ... },
5132 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005133 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005134 in topology data.
5135 """
5136 graphDict = {}
5137 try:
5138 links = self.links()
5139 links = json.loads( links )
5140 devices = self.devices()
5141 devices = json.loads( devices )
5142 idToDevice = {}
5143 for device in devices:
5144 idToDevice[ device[ 'id' ] ] = device
5145 if includeHost:
5146 hosts = self.hosts()
5147 # FIXME: support 'includeHost' argument
5148 for link in links:
5149 nodeA = link[ 'src' ][ 'device' ]
5150 nodeB = link[ 'dst' ][ 'device' ]
5151 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005152 if nodeA not in graphDict.keys():
5153 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005154 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005155 'type': idToDevice[ nodeA ][ 'type' ],
5156 'available': idToDevice[ nodeA ][ 'available' ],
5157 'role': idToDevice[ nodeA ][ 'role' ],
5158 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5159 'hw': idToDevice[ nodeA ][ 'hw' ],
5160 'sw': idToDevice[ nodeA ][ 'sw' ],
5161 'serial': idToDevice[ nodeA ][ 'serial' ],
5162 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005163 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005164 else:
5165 # Assert nodeB is not connected to any current links of nodeA
5166 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005167 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5168 'type': link[ 'type' ],
5169 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005170 return graphDict
5171 except ( TypeError, ValueError ):
5172 main.log.exception( self.name + ": Object not as expected" )
5173 return None
5174 except KeyError:
5175 main.log.exception( self.name + ": KeyError exception found" )
5176 return None
5177 except AssertionError:
5178 main.log.exception( self.name + ": AssertionError exception found" )
5179 return None
5180 except pexpect.EOF:
5181 main.log.error( self.name + ": EOF exception found" )
5182 main.log.error( self.name + ": " + self.handle.before )
5183 return None
5184 except Exception:
5185 main.log.exception( self.name + ": Uncaught exception!" )
5186 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005187
5188 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005189 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005190 Send command to check intent-perf summary
5191 Returns: dictionary for intent-perf summary
5192 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005193 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005194 cmd = "intent-perf -s"
5195 respDic = {}
5196 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005197 assert resp is not None, "Error in sendline"
5198 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005199 try:
5200 # Generate the dictionary to return
5201 for l in resp.split( "\n" ):
5202 # Delete any white space in line
5203 temp = re.sub( r'\s+', '', l )
5204 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005205 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005206
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005207 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005208 main.log.exception( self.name + ": Object not as expected" )
5209 return None
5210 except KeyError:
5211 main.log.exception( self.name + ": KeyError exception found" )
5212 return None
5213 except AssertionError:
5214 main.log.exception( self.name + ": AssertionError exception found" )
5215 return None
5216 except pexpect.EOF:
5217 main.log.error( self.name + ": EOF exception found" )
5218 main.log.error( self.name + ": " + self.handle.before )
5219 return None
5220 except Exception:
5221 main.log.exception( self.name + ": Uncaught exception!" )
5222 return None
5223 return respDic
5224
Chiyu Chengec63bde2016-11-17 18:11:36 -08005225 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005226 """
5227 Searches the latest ONOS log file for the given search term and
5228 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005229
chengchiyu08303a02016-09-08 17:40:26 -07005230 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005231 searchTerm:
5232 The string to grep from the ONOS log.
5233 startLine:
5234 The term that decides which line is the start to search the searchTerm in
5235 the karaf log. For now, startTerm only works in 'first' mode.
5236 logNum:
5237 In some extreme cases, one karaf log is not big enough to contain all the
5238 information.Because of this, search mutiply logs is necessary to capture
5239 the right result. logNum is the number of karaf logs that we need to search
5240 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005241 mode:
5242 all: return all the strings that contain the search term
5243 last: return the last string that contains the search term
5244 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005245 num: return the number of times that the searchTerm appears in the log
5246 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005247 """
5248 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005249 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005250 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005251 logPath = '/opt/onos/log/karaf.log.'
5252 logPaths = '/opt/onos/log/karaf.log'
5253 for i in range( 1, logNum ):
5254 logPaths = logPath + str( i ) + " " + logPaths
5255 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005256 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005257 # 100000000 is just a extreme large number to make sure this function can
5258 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005259 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005260 if mode == 'all':
5261 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005262 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005263 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005264 elif mode == 'first':
5265 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5266 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005267 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005268 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005269 return num
You Wang6d301d42017-04-21 10:49:33 -07005270 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005271 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005272 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005273 else:
5274 main.log.error( self.name + " unsupported mode" )
5275 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005276 before = self.sendline( cmd )
5277 before = before.splitlines()
5278 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005279 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005280 return returnLines
5281 except AssertionError:
5282 main.log.error( self.name + " searchTerm is not string type" )
5283 return None
5284 except pexpect.EOF:
5285 main.log.error( self.name + ": EOF exception found" )
5286 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005287 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005288 except pexpect.TIMEOUT:
5289 main.log.error( self.name + ": TIMEOUT exception found" )
5290 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005291 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005292 except Exception:
5293 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005294 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005295
5296 def vplsShow( self, jsonFormat=True ):
5297 """
5298 Description: Returns result of onos:vpls show, which should list the
5299 configured VPLS networks and the assigned interfaces.
5300 Optional:
5301 * jsonFormat: enable json formatting of output
5302 Returns:
5303 The output of the command or None on error.
5304 """
5305 try:
5306 cmdStr = "vpls show"
5307 if jsonFormat:
5308 raise NotImplementedError
5309 cmdStr += " -j"
5310 handle = self.sendline( cmdStr )
5311 assert handle is not None, "Error in sendline"
5312 assert "Command not found:" not in handle, handle
5313 return handle
5314 except AssertionError:
5315 main.log.exception( "" )
5316 return None
5317 except TypeError:
5318 main.log.exception( self.name + ": Object not as expected" )
5319 return None
5320 except pexpect.EOF:
5321 main.log.error( self.name + ": EOF exception found" )
5322 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005323 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005324 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005325 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005326 return None
5327 except Exception:
5328 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005329 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005330
5331 def parseVplsShow( self ):
5332 """
5333 Parse the cli output of 'vpls show' into json output. This is required
5334 as there is currently no json output available.
5335 """
5336 try:
5337 output = []
5338 raw = self.vplsShow( jsonFormat=False )
5339 namePat = "VPLS name: (?P<name>\w+)"
5340 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5341 encapPat = "Encapsulation: (?P<encap>\w+)"
5342 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5343 mIter = re.finditer( pattern, raw )
5344 for match in mIter:
5345 item = {}
5346 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005347 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005348 if ifaces == [ "" ]:
5349 ifaces = []
5350 item[ 'interfaces' ] = ifaces
5351 encap = match.group( 'encap' )
5352 if encap != 'NONE':
5353 item[ 'encapsulation' ] = encap.lower()
5354 output.append( item )
5355 return output
5356 except Exception:
5357 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005358 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005359
5360 def vplsList( self, jsonFormat=True ):
5361 """
5362 Description: Returns result of onos:vpls list, which should list the
5363 configured VPLS networks.
5364 Optional:
5365 * jsonFormat: enable json formatting of output
5366 """
5367 try:
5368 cmdStr = "vpls list"
5369 if jsonFormat:
5370 raise NotImplementedError
5371 cmdStr += " -j"
5372 handle = self.sendline( cmdStr )
5373 assert handle is not None, "Error in sendline"
5374 assert "Command not found:" not in handle, handle
5375 return handle
5376 except AssertionError:
5377 main.log.exception( "" )
5378 return None
5379 except TypeError:
5380 main.log.exception( self.name + ": Object not as expected" )
5381 return None
5382 except pexpect.EOF:
5383 main.log.error( self.name + ": EOF exception found" )
5384 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005385 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005386 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005387 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005388 return None
5389 except Exception:
5390 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005391 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005392
5393 def vplsCreate( self, network ):
5394 """
5395 CLI command to create a new VPLS network.
5396 Required arguments:
5397 network - String name of the network to create.
5398 returns:
5399 main.TRUE on success and main.FALSE on failure
5400 """
5401 try:
5402 network = str( network )
5403 cmdStr = "vpls create "
5404 cmdStr += network
5405 output = self.sendline( cmdStr )
5406 assert output is not None, "Error in sendline"
5407 assert "Command not found:" not in output, output
5408 assert "Error executing command" not in output, output
5409 assert "VPLS already exists:" not in output, output
5410 return main.TRUE
5411 except AssertionError:
5412 main.log.exception( "" )
5413 return main.FALSE
5414 except TypeError:
5415 main.log.exception( self.name + ": Object not as expected" )
5416 return main.FALSE
5417 except pexpect.EOF:
5418 main.log.error( self.name + ": EOF exception found" )
5419 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005420 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005421 except Exception:
5422 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005423 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005424
5425 def vplsDelete( self, network ):
5426 """
5427 CLI command to delete a VPLS network.
5428 Required arguments:
5429 network - Name of the network to delete.
5430 returns:
5431 main.TRUE on success and main.FALSE on failure
5432 """
5433 try:
5434 network = str( network )
5435 cmdStr = "vpls delete "
5436 cmdStr += network
5437 output = self.sendline( cmdStr )
5438 assert output is not None, "Error in sendline"
5439 assert "Command not found:" not in output, output
5440 assert "Error executing command" not in output, output
5441 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005442 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005443 return main.TRUE
5444 except AssertionError:
5445 main.log.exception( "" )
5446 return main.FALSE
5447 except TypeError:
5448 main.log.exception( self.name + ": Object not as expected" )
5449 return main.FALSE
5450 except pexpect.EOF:
5451 main.log.error( self.name + ": EOF exception found" )
5452 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005453 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005454 except Exception:
5455 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005456 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005457
5458 def vplsAddIface( self, network, iface ):
5459 """
5460 CLI command to add an interface to a VPLS network.
5461 Required arguments:
5462 network - Name of the network to add the interface to.
5463 iface - The ONOS name for an interface.
5464 returns:
5465 main.TRUE on success and main.FALSE on failure
5466 """
5467 try:
5468 network = str( network )
5469 iface = str( iface )
5470 cmdStr = "vpls add-if "
5471 cmdStr += network + " " + iface
5472 output = self.sendline( cmdStr )
5473 assert output is not None, "Error in sendline"
5474 assert "Command not found:" not in output, output
5475 assert "Error executing command" not in output, output
5476 assert "already associated to network" not in output, output
5477 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005478 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005479 return main.TRUE
5480 except AssertionError:
5481 main.log.exception( "" )
5482 return main.FALSE
5483 except TypeError:
5484 main.log.exception( self.name + ": Object not as expected" )
5485 return main.FALSE
5486 except pexpect.EOF:
5487 main.log.error( self.name + ": EOF exception found" )
5488 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005489 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005490 except Exception:
5491 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005492 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005493
5494 def vplsRemIface( self, network, iface ):
5495 """
5496 CLI command to remove an interface from a VPLS network.
5497 Required arguments:
5498 network - Name of the network to remove the interface from.
5499 iface - Name of the interface to remove.
5500 returns:
5501 main.TRUE on success and main.FALSE on failure
5502 """
5503 try:
5504 iface = str( iface )
5505 cmdStr = "vpls rem-if "
5506 cmdStr += network + " " + iface
5507 output = self.sendline( cmdStr )
5508 assert output is not None, "Error in sendline"
5509 assert "Command not found:" not in output, output
5510 assert "Error executing command" not in output, output
5511 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005512 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005513 return main.TRUE
5514 except AssertionError:
5515 main.log.exception( "" )
5516 return main.FALSE
5517 except TypeError:
5518 main.log.exception( self.name + ": Object not as expected" )
5519 return main.FALSE
5520 except pexpect.EOF:
5521 main.log.error( self.name + ": EOF exception found" )
5522 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005523 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005524 except Exception:
5525 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005526 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005527
5528 def vplsClean( self ):
5529 """
5530 Description: Clears the VPLS app configuration.
5531 Returns: main.TRUE on success and main.FALSE on failure
5532 """
5533 try:
5534 cmdStr = "vpls clean"
5535 handle = self.sendline( cmdStr )
5536 assert handle is not None, "Error in sendline"
5537 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005538 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005539 return handle
5540 except AssertionError:
5541 main.log.exception( "" )
5542 return main.FALSE
5543 except TypeError:
5544 main.log.exception( self.name + ": Object not as expected" )
5545 return main.FALSE
5546 except pexpect.EOF:
5547 main.log.error( self.name + ": EOF exception found" )
5548 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005549 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005550 except Exception:
5551 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005552 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005553
5554 def vplsSetEncap( self, network, encapType ):
5555 """
5556 CLI command to add an interface to a VPLS network.
5557 Required arguments:
5558 network - Name of the network to create.
5559 encapType - Type of encapsulation.
5560 returns:
5561 main.TRUE on success and main.FALSE on failure
5562 """
5563 try:
5564 network = str( network )
5565 encapType = str( encapType ).upper()
5566 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5567 cmdStr = "vpls set-encap "
5568 cmdStr += network + " " + encapType
5569 output = self.sendline( cmdStr )
5570 assert output is not None, "Error in sendline"
5571 assert "Command not found:" not in output, output
5572 assert "Error executing command" not in output, output
5573 assert "already associated to network" not in output, output
5574 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005575 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005576 return main.TRUE
5577 except AssertionError:
5578 main.log.exception( "" )
5579 return main.FALSE
5580 except TypeError:
5581 main.log.exception( self.name + ": Object not as expected" )
5582 return main.FALSE
5583 except pexpect.EOF:
5584 main.log.error( self.name + ": EOF exception found" )
5585 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005586 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005587 except Exception:
5588 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005589 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005590
5591 def interfaces( self, jsonFormat=True ):
5592 """
5593 Description: Returns result of interfaces command.
5594 Optional:
5595 * jsonFormat: enable json formatting of output
5596 Returns:
5597 The output of the command or None on error.
5598 """
5599 try:
5600 cmdStr = "interfaces"
5601 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005602 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005603 cmdStr += " -j"
5604 handle = self.sendline( cmdStr )
5605 assert handle is not None, "Error in sendline"
5606 assert "Command not found:" not in handle, handle
5607 return handle
5608 except AssertionError:
5609 main.log.exception( "" )
5610 return None
5611 except TypeError:
5612 main.log.exception( self.name + ": Object not as expected" )
5613 return None
5614 except pexpect.EOF:
5615 main.log.error( self.name + ": EOF exception found" )
5616 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005617 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005618 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005619 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005620 return None
5621 except Exception:
5622 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005623 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005624
5625 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005626 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005627 Get the timestamp of searchTerm from karaf log.
5628
5629 Arguments:
5630 splitTerm_before and splitTerm_after:
5631
5632 The terms that split the string that contains the timeStamp of
5633 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5634 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5635 and the splitTerm_after is "x"
5636
5637 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005638 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005639 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005640 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005641 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005642 return main.ERROR
5643 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005644 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005645 main.log.warn( "Captured timestamp string is empty" )
5646 return main.ERROR
5647 lines = lines[ 0 ]
5648 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005649 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005650 # get the target value
5651 line = lines.split( splitTerm_before )
5652 key = line[ 1 ].split( splitTerm_after )
5653 return int( key[ 0 ] )
5654 except IndexError:
5655 main.log.warn( "Index Error!" )
5656 return main.ERROR
5657 except AssertionError:
5658 main.log.warn( "Search Term Not Found " )
5659 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005660
5661 def workQueueAdd( self, queueName, value ):
5662 """
5663 CLI command to add a string to the specified Work Queue.
5664 This function uses the distributed primitives test app, which
5665 gives some cli access to distributed primitives for testing
5666 purposes only.
5667
5668 Required arguments:
5669 queueName - The name of the queue to add to
5670 value - The value to add to the queue
5671 returns:
5672 main.TRUE on success, main.FALSE on failure and
5673 main.ERROR on error.
5674 """
5675 try:
5676 queueName = str( queueName )
5677 value = str( value )
5678 prefix = "work-queue-test"
5679 operation = "add"
5680 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5681 output = self.distPrimitivesSend( cmdStr )
5682 if "Invalid operation name" in output:
5683 main.log.warn( output )
5684 return main.ERROR
5685 elif "Done" in output:
5686 return main.TRUE
5687 except TypeError:
5688 main.log.exception( self.name + ": Object not as expected" )
5689 return main.ERROR
5690 except Exception:
5691 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005692 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005693
5694 def workQueueAddMultiple( self, queueName, value1, value2 ):
5695 """
5696 CLI command to add two strings to the specified Work Queue.
5697 This function uses the distributed primitives test app, which
5698 gives some cli access to distributed primitives for testing
5699 purposes only.
5700
5701 Required arguments:
5702 queueName - The name of the queue to add to
5703 value1 - The first value to add to the queue
5704 value2 - The second value to add to the queue
5705 returns:
5706 main.TRUE on success, main.FALSE on failure and
5707 main.ERROR on error.
5708 """
5709 try:
5710 queueName = str( queueName )
5711 value1 = str( value1 )
5712 value2 = str( value2 )
5713 prefix = "work-queue-test"
5714 operation = "addMultiple"
5715 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5716 output = self.distPrimitivesSend( cmdStr )
5717 if "Invalid operation name" in output:
5718 main.log.warn( output )
5719 return main.ERROR
5720 elif "Done" in output:
5721 return main.TRUE
5722 except TypeError:
5723 main.log.exception( self.name + ": Object not as expected" )
5724 return main.ERROR
5725 except Exception:
5726 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005727 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005728
5729 def workQueueTakeAndComplete( self, queueName, number=1 ):
5730 """
5731 CLI command to take a value from the specified Work Queue and compelte it.
5732 This function uses the distributed primitives test app, which
5733 gives some cli access to distributed primitives for testing
5734 purposes only.
5735
5736 Required arguments:
5737 queueName - The name of the queue to add to
5738 number - The number of items to take and complete
5739 returns:
5740 main.TRUE on success, main.FALSE on failure and
5741 main.ERROR on error.
5742 """
5743 try:
5744 queueName = str( queueName )
5745 number = str( int( number ) )
5746 prefix = "work-queue-test"
5747 operation = "takeAndComplete"
5748 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5749 output = self.distPrimitivesSend( cmdStr )
5750 if "Invalid operation name" in output:
5751 main.log.warn( output )
5752 return main.ERROR
5753 elif "Done" in output:
5754 return main.TRUE
5755 except TypeError:
5756 main.log.exception( self.name + ": Object not as expected" )
5757 return main.ERROR
5758 except Exception:
5759 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005760 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005761
5762 def workQueueDestroy( self, queueName ):
5763 """
5764 CLI command to destroy the specified Work Queue.
5765 This function uses the distributed primitives test app, which
5766 gives some cli access to distributed primitives for testing
5767 purposes only.
5768
5769 Required arguments:
5770 queueName - The name of the queue to add to
5771 returns:
5772 main.TRUE on success, main.FALSE on failure and
5773 main.ERROR on error.
5774 """
5775 try:
5776 queueName = str( queueName )
5777 prefix = "work-queue-test"
5778 operation = "destroy"
5779 cmdStr = " ".join( [ prefix, queueName, operation ] )
5780 output = self.distPrimitivesSend( cmdStr )
5781 if "Invalid operation name" in output:
5782 main.log.warn( output )
5783 return main.ERROR
5784 return main.TRUE
5785 except TypeError:
5786 main.log.exception( self.name + ": Object not as expected" )
5787 return main.ERROR
5788 except Exception:
5789 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005790 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005791
5792 def workQueueTotalPending( self, queueName ):
5793 """
5794 CLI command to get the Total Pending items of the specified Work Queue.
5795 This function uses the distributed primitives test app, which
5796 gives some cli access to distributed primitives for testing
5797 purposes only.
5798
5799 Required arguments:
5800 queueName - The name of the queue to add to
5801 returns:
5802 The number of Pending items in the specified work queue or
5803 None on error
5804 """
5805 try:
5806 queueName = str( queueName )
5807 prefix = "work-queue-test"
5808 operation = "totalPending"
5809 cmdStr = " ".join( [ prefix, queueName, operation ] )
5810 output = self.distPrimitivesSend( cmdStr )
5811 pattern = r'\d+'
5812 if "Invalid operation name" in output:
5813 main.log.warn( output )
5814 return None
5815 else:
5816 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005817 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005818 except ( AttributeError, TypeError ):
5819 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5820 return None
5821 except Exception:
5822 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005823 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005824
5825 def workQueueTotalCompleted( self, queueName ):
5826 """
5827 CLI command to get the Total Completed items of the specified Work Queue.
5828 This function uses the distributed primitives test app, which
5829 gives some cli access to distributed primitives for testing
5830 purposes only.
5831
5832 Required arguments:
5833 queueName - The name of the queue to add to
5834 returns:
5835 The number of complete items in the specified work queue or
5836 None on error
5837 """
5838 try:
5839 queueName = str( queueName )
5840 prefix = "work-queue-test"
5841 operation = "totalCompleted"
5842 cmdStr = " ".join( [ prefix, queueName, operation ] )
5843 output = self.distPrimitivesSend( cmdStr )
5844 pattern = r'\d+'
5845 if "Invalid operation name" in output:
5846 main.log.warn( output )
5847 return None
5848 else:
5849 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005850 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005851 except ( AttributeError, TypeError ):
5852 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5853 return None
5854 except Exception:
5855 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005856 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005857
5858 def workQueueTotalInProgress( self, queueName ):
5859 """
5860 CLI command to get the Total In Progress items of the specified Work Queue.
5861 This function uses the distributed primitives test app, which
5862 gives some cli access to distributed primitives for testing
5863 purposes only.
5864
5865 Required arguments:
5866 queueName - The name of the queue to add to
5867 returns:
5868 The number of In Progress items in the specified work queue or
5869 None on error
5870 """
5871 try:
5872 queueName = str( queueName )
5873 prefix = "work-queue-test"
5874 operation = "totalInProgress"
5875 cmdStr = " ".join( [ prefix, queueName, operation ] )
5876 output = self.distPrimitivesSend( cmdStr )
5877 pattern = r'\d+'
5878 if "Invalid operation name" in output:
5879 main.log.warn( output )
5880 return None
5881 else:
5882 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005883 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005884 except ( AttributeError, TypeError ):
5885 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5886 return None
5887 except Exception:
5888 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005889 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005890
5891 def events( self, args='-a' ):
5892 """
5893 Description: Returns events -a command output
5894 Optional:
5895 add other arguments
5896 """
5897 try:
5898 cmdStr = "events"
5899 if args:
5900 cmdStr += " " + args
5901 handle = self.sendline( cmdStr )
5902 assert handle is not None, "Error in sendline"
5903 assert "Command not found:" not in handle, handle
5904 return handle
5905 except AssertionError:
5906 main.log.exception( "" )
5907 return None
5908 except TypeError:
5909 main.log.exception( self.name + ": Object not as expected" )
5910 return None
5911 except pexpect.EOF:
5912 main.log.error( self.name + ": EOF exception found" )
5913 main.log.error( self.name + ": " + self.handle.before )
5914 main.cleanAndExit()
5915 except Exception:
5916 main.log.exception( self.name + ": Uncaught exception!" )
5917 main.cleanAndExit()
5918
5919 def getMaster( self, deviceID ):
5920 """
5921 Description: Obtains current master using "roles" command for a specific deviceID
5922 """
5923 try:
5924 return str( self.getRole( deviceID )[ 'master' ] )
5925 except AssertionError:
5926 main.log.exception( "" )
5927 return None
5928 except TypeError:
5929 main.log.exception( self.name + ": Object not as expected" )
5930 return None
5931 except pexpect.EOF:
5932 main.log.error( self.name + ": EOF exception found" )
5933 main.log.error( self.name + ": " + self.handle.before )
5934 main.cleanAndExit()
5935 except Exception:
5936 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07005937 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08005938
5939 def issu( self ):
5940 """
5941 Short summary of In-Service Software Upgrade status
5942
5943 Returns the output of the cli command or None on Error
5944 """
5945 try:
5946 cmdStr = "issu"
5947 handle = self.sendline( cmdStr )
5948 assert handle is not None, "Error in sendline"
5949 assert "Command not found:" not in handle, handle
5950 assert "Unsupported command:" not in handle, handle
5951 return handle
5952 except AssertionError:
5953 main.log.exception( "" )
5954 return None
5955 except TypeError:
5956 main.log.exception( self.name + ": Object not as expected" )
5957 return None
5958 except pexpect.EOF:
5959 main.log.error( self.name + ": EOF exception found" )
5960 main.log.error( self.name + ": " + self.handle.before )
5961 main.cleanAndExit()
5962 except Exception:
5963 main.log.exception( self.name + ": Uncaught exception!" )
5964 main.cleanAndExit()
5965
5966 def issuInit( self ):
5967 """
5968 Initiates an In-Service Software Upgrade
5969
5970 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5971 """
5972 try:
5973 cmdStr = "issu init"
5974 handle = self.sendline( cmdStr )
5975 assert handle is not None, "Error in sendline"
5976 assert "Command not found:" not in handle, handle
5977 assert "Unsupported command:" not in handle, handle
5978 if "Initialized" in handle:
5979 return main.TRUE
5980 else:
5981 return main.FALSE
5982 except AssertionError:
5983 main.log.exception( "" )
5984 return main.ERROR
5985 except TypeError:
5986 main.log.exception( self.name + ": Object not as expected" )
5987 return main.ERROR
5988 except pexpect.EOF:
5989 main.log.error( self.name + ": EOF exception found" )
5990 main.log.error( self.name + ": " + self.handle.before )
5991 main.cleanAndExit()
5992 except Exception:
5993 main.log.exception( self.name + ": Uncaught exception!" )
5994 main.cleanAndExit()
5995
5996 def issuUpgrade( self ):
5997 """
5998 Transitions stores to upgraded nodes
5999
6000 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6001 """
6002 try:
6003 cmdStr = "issu upgrade"
6004 handle = self.sendline( cmdStr )
6005 assert handle is not None, "Error in sendline"
6006 assert "Command not found:" not in handle, handle
6007 assert "Unsupported command:" not in handle, handle
6008 if "Upgraded" in handle:
6009 return main.TRUE
6010 else:
6011 return main.FALSE
6012 except AssertionError:
6013 main.log.exception( "" )
6014 return main.ERROR
6015 except TypeError:
6016 main.log.exception( self.name + ": Object not as expected" )
6017 return main.ERROR
6018 except pexpect.EOF:
6019 main.log.error( self.name + ": EOF exception found" )
6020 main.log.error( self.name + ": " + self.handle.before )
6021 main.cleanAndExit()
6022 except Exception:
6023 main.log.exception( self.name + ": Uncaught exception!" )
6024 main.cleanAndExit()
6025
6026 def issuCommit( self ):
6027 """
6028 Finalizes an In-Service Software Upgrade
6029
6030 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6031 """
6032 try:
6033 cmdStr = "issu commit"
6034 handle = self.sendline( cmdStr )
6035 assert handle is not None, "Error in sendline"
6036 assert "Command not found:" not in handle, handle
6037 assert "Unsupported command:" not in handle, handle
6038 # TODO: Check the version returned by this command
6039 if "Committed version" in handle:
6040 return main.TRUE
6041 else:
6042 return main.FALSE
6043 except AssertionError:
6044 main.log.exception( "" )
6045 return main.ERROR
6046 except TypeError:
6047 main.log.exception( self.name + ": Object not as expected" )
6048 return main.ERROR
6049 except pexpect.EOF:
6050 main.log.error( self.name + ": EOF exception found" )
6051 main.log.error( self.name + ": " + self.handle.before )
6052 main.cleanAndExit()
6053 except Exception:
6054 main.log.exception( self.name + ": Uncaught exception!" )
6055 main.cleanAndExit()
6056
6057 def issuRollback( self ):
6058 """
6059 Rolls back an In-Service Software Upgrade
6060
6061 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6062 """
6063 try:
6064 cmdStr = "issu rollback"
6065 handle = self.sendline( cmdStr )
6066 assert handle is not None, "Error in sendline"
6067 assert "Command not found:" not in handle, handle
6068 assert "Unsupported command:" not in handle, handle
6069 # TODO: Check the version returned by this command
6070 if "Rolled back to version" in handle:
6071 return main.TRUE
6072 else:
6073 return main.FALSE
6074 except AssertionError:
6075 main.log.exception( "" )
6076 return main.ERROR
6077 except TypeError:
6078 main.log.exception( self.name + ": Object not as expected" )
6079 return main.ERROR
6080 except pexpect.EOF:
6081 main.log.error( self.name + ": EOF exception found" )
6082 main.log.error( self.name + ": " + self.handle.before )
6083 main.cleanAndExit()
6084 except Exception:
6085 main.log.exception( self.name + ": Uncaught exception!" )
6086 main.cleanAndExit()
6087
6088 def issuReset( self ):
6089 """
6090 Resets the In-Service Software Upgrade status after a rollback
6091
6092 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6093 """
6094 try:
6095 cmdStr = "issu reset"
6096 handle = self.sendline( cmdStr )
6097 assert handle is not None, "Error in sendline"
6098 assert "Command not found:" not in handle, handle
6099 assert "Unsupported command:" not in handle, handle
6100 # TODO: Check the version returned by this command
6101 if "Reset version" in handle:
6102 return main.TRUE
6103 else:
6104 return main.FALSE
6105 except AssertionError:
6106 main.log.exception( "" )
6107 return main.ERROR
6108 except TypeError:
6109 main.log.exception( self.name + ": Object not as expected" )
6110 return main.ERROR
6111 except pexpect.EOF:
6112 main.log.error( self.name + ": EOF exception found" )
6113 main.log.error( self.name + ": " + self.handle.before )
6114 main.cleanAndExit()
6115 except Exception:
6116 main.log.exception( self.name + ": Uncaught exception!" )
6117 main.cleanAndExit()
6118
6119 def issuStatus( self ):
6120 """
6121 Status of an In-Service Software Upgrade
6122
6123 Returns the output of the cli command or None on Error
6124 """
6125 try:
6126 cmdStr = "issu status"
6127 handle = self.sendline( cmdStr )
6128 assert handle is not None, "Error in sendline"
6129 assert "Command not found:" not in handle, handle
6130 assert "Unsupported command:" not in handle, handle
6131 return handle
6132 except AssertionError:
6133 main.log.exception( "" )
6134 return None
6135 except TypeError:
6136 main.log.exception( self.name + ": Object not as expected" )
6137 return None
6138 except pexpect.EOF:
6139 main.log.error( self.name + ": EOF exception found" )
6140 main.log.error( self.name + ": " + self.handle.before )
6141 main.cleanAndExit()
6142 except Exception:
6143 main.log.exception( self.name + ": Uncaught exception!" )
6144 main.cleanAndExit()
6145
6146 def issuVersion( self ):
6147 """
6148 Get the version of an In-Service Software Upgrade
6149
6150 Returns the output of the cli command or None on Error
6151 """
6152 try:
6153 cmdStr = "issu version"
6154 handle = self.sendline( cmdStr )
6155 assert handle is not None, "Error in sendline"
6156 assert "Command not found:" not in handle, handle
6157 assert "Unsupported command:" not in handle, handle
6158 return handle
6159 except AssertionError:
6160 main.log.exception( "" )
6161 return None
6162 except TypeError:
6163 main.log.exception( self.name + ": Object not as expected" )
6164 return None
6165 except pexpect.EOF:
6166 main.log.error( self.name + ": EOF exception found" )
6167 main.log.error( self.name + ": " + self.handle.before )
6168 main.cleanAndExit()
6169 except Exception:
6170 main.log.exception( self.name + ": Uncaught exception!" )
6171 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006172
6173 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6174 """
6175 Create a multicast route by calling 'mcast-join' command
6176 sIP: source IP of the multicast route
6177 groupIP: group IP of the multicast route
6178 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6179 dPorts: a list of destination ports of the multicast route
6180 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6181 """
6182 try:
6183 cmdStr = "mcast-join"
6184 cmdStr += " " + str( sIP )
6185 cmdStr += " " + str( groupIP )
6186 cmdStr += " " + str( sPort )
6187 assert isinstance( dPorts, list )
6188 for dPort in dPorts:
6189 cmdStr += " " + str( dPort )
6190 handle = self.sendline( cmdStr )
6191 assert handle is not None, "Error in sendline"
6192 assert "Command not found:" not in handle, handle
6193 assert "Unsupported command:" not in handle, handle
6194 assert "Error executing command" not in handle, handle
6195 if "Added the mcast route" in handle:
6196 return main.TRUE
6197 else:
6198 return main.FALSE
6199 except AssertionError:
6200 main.log.exception( "" )
6201 return None
6202 except TypeError:
6203 main.log.exception( self.name + ": Object not as expected" )
6204 return None
6205 except pexpect.EOF:
6206 main.log.error( self.name + ": EOF exception found" )
6207 main.log.error( self.name + ": " + self.handle.before )
6208 main.cleanAndExit()
6209 except Exception:
6210 main.log.exception( self.name + ": Uncaught exception!" )
6211 main.cleanAndExit()
6212
6213 def mcastDelete( self, sIP, groupIP, dPorts ):
6214 """
6215 Delete a multicast route by calling 'mcast-delete' command
6216 sIP: source IP of the multicast route
6217 groupIP: group IP of the multicast route
6218 dPorts: a list of destination ports of the multicast route
6219 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6220 """
6221 try:
6222 cmdStr = "mcast-delete"
6223 cmdStr += " " + str( sIP )
6224 cmdStr += " " + str( groupIP )
6225 assert isinstance( dPorts, list )
6226 for dPort in dPorts:
6227 cmdStr += " " + str( dPort )
6228 handle = self.sendline( cmdStr )
6229 assert handle is not None, "Error in sendline"
6230 assert "Command not found:" not in handle, handle
6231 assert "Unsupported command:" not in handle, handle
6232 assert "Error executing command" not in handle, handle
6233 if "Updated the mcast route" in handle:
6234 return main.TRUE
6235 else:
6236 return main.FALSE
6237 except AssertionError:
6238 main.log.exception( "" )
6239 return None
6240 except TypeError:
6241 main.log.exception( self.name + ": Object not as expected" )
6242 return None
6243 except pexpect.EOF:
6244 main.log.error( self.name + ": EOF exception found" )
6245 main.log.error( self.name + ": " + self.handle.before )
6246 main.cleanAndExit()
6247 except Exception:
6248 main.log.exception( self.name + ": Uncaught exception!" )
6249 main.cleanAndExit()
6250
6251 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6252 """
6253 Create a multicast route by calling 'mcast-host-join' command
6254 sAddr: we can provide * for ASM or a specific address for SSM
6255 gAddr: specifies multicast group address
6256 srcs: a list of the source connect points e.g. ["of:0000000000000003/12"]
6257 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6258 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6259 """
6260 try:
6261 cmdStr = "mcast-host-join"
6262 cmdStr += " -sAddr " + str( sAddr )
6263 cmdStr += " -gAddr " + str( gAddr )
6264 assert isinstance( srcs, list )
6265 for src in srcs:
6266 cmdStr += " -srcs " + str( src )
6267 assert isinstance( sinks, list )
6268 for sink in sinks:
6269 cmdStr += " -sinks " + str( sink )
6270 handle = self.sendline( cmdStr )
6271 assert handle is not None, "Error in sendline"
6272 assert "Command not found:" not in handle, handle
6273 assert "Unsupported command:" not in handle, handle
6274 assert "Error executing command" not in handle, handle
6275 if "Added the mcast route" in handle:
6276 return main.TRUE
6277 else:
6278 return main.FALSE
6279 except AssertionError:
6280 main.log.exception( "" )
6281 return None
6282 except TypeError:
6283 main.log.exception( self.name + ": Object not as expected" )
6284 return None
6285 except pexpect.EOF:
6286 main.log.error( self.name + ": EOF exception found" )
6287 main.log.error( self.name + ": " + self.handle.before )
6288 main.cleanAndExit()
6289 except Exception:
6290 main.log.exception( self.name + ": Uncaught exception!" )
6291 main.cleanAndExit()
6292
6293 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6294 """
6295 Delete multicast sink(s) by calling 'mcast-host-delete' command
6296 sAddr: we can provide * for ASM or a specific address for SSM
6297 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006298 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006299 will delete the route if not specified
6300 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6301 """
6302 try:
6303 cmdStr = "mcast-host-delete"
6304 cmdStr += " -sAddr " + str( sAddr )
6305 cmdStr += " -gAddr " + str( gAddr )
6306 if host:
6307 cmdStr += " -h " + str( host )
6308 handle = self.sendline( cmdStr )
6309 assert handle is not None, "Error in sendline"
6310 assert "Command not found:" not in handle, handle
6311 assert "Unsupported command:" not in handle, handle
6312 assert "Error executing command" not in handle, handle
6313 if "Updated the mcast route" in handle:
6314 return main.TRUE
6315 elif "Deleted the mcast route" in handle:
6316 return main.TRUE
6317 else:
6318 return main.FALSE
6319 except AssertionError:
6320 main.log.exception( "" )
6321 return None
6322 except TypeError:
6323 main.log.exception( self.name + ": Object not as expected" )
6324 return None
6325 except pexpect.EOF:
6326 main.log.error( self.name + ": EOF exception found" )
6327 main.log.error( self.name + ": " + self.handle.before )
6328 main.cleanAndExit()
6329 except Exception:
6330 main.log.exception( self.name + ": Uncaught exception!" )
6331 main.cleanAndExit()
6332
6333 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6334 """
6335 Delete multicast src(s) by calling 'mcast-source-delete' command
6336 sAddr: we can provide * for ASM or a specific address for SSM
6337 gAddr: specifies multicast group address
6338 srcs: a list of connect points of the sources e.g. ["00:AA:00:00:01:05/40"],
6339 will delete the route if not specified
6340 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6341 """
6342 try:
6343 cmdStr = "mcast-source-delete"
6344 cmdStr += " -sAddr " + str( sAddr )
6345 cmdStr += " -gAddr " + str( gAddr )
6346 if srcs:
6347 assert isinstance( srcs, list )
6348 for src in srcs:
6349 cmdStr += " -src " + str( src )
6350 handle = self.sendline( cmdStr )
6351 assert handle is not None, "Error in sendline"
6352 assert "Command not found:" not in handle, handle
6353 assert "Unsupported command:" not in handle, handle
6354 assert "Error executing command" not in handle, handle
6355 if "Updated the mcast route" in handle:
6356 return main.TRUE
6357 elif "Deleted the mcast route" in handle:
6358 return main.TRUE
6359 else:
6360 return main.FALSE
6361 except AssertionError:
6362 main.log.exception( "" )
6363 return None
6364 except TypeError:
6365 main.log.exception( self.name + ": Object not as expected" )
6366 return None
6367 except pexpect.EOF:
6368 main.log.error( self.name + ": EOF exception found" )
6369 main.log.error( self.name + ": " + self.handle.before )
6370 main.cleanAndExit()
6371 except Exception:
6372 main.log.exception( self.name + ": Uncaught exception!" )
6373 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006374
6375 def netcfg( self, jsonFormat=True, args="" ):
6376 """
6377 Run netcfg cli command with given args
6378 """
6379 try:
6380 cmdStr = "netcfg"
6381 if jsonFormat:
6382 cmdStr = cmdStr + " -j"
6383 if args:
6384 cmdStr = cmdStr + " " + str( args )
6385 handle = self.sendline( cmdStr )
6386 assert handle is not None, "Error in sendline"
6387 assert "Command not found:" not in handle, handle
6388 assert "Unsupported command:" not in handle, handle
6389 assert "Error executing command" not in handle, handle
6390 return handle
6391 except AssertionError:
6392 main.log.exception( "" )
6393 return None
6394 except TypeError:
6395 main.log.exception( self.name + ": Object not as expected" )
6396 return None
6397 except pexpect.EOF:
6398 main.log.error( self.name + ": EOF exception found" )
6399 main.log.error( self.name + ": " + self.handle.before )
6400 main.cleanAndExit()
6401 except Exception:
6402 main.log.exception( self.name + ": Uncaught exception!" )
6403 main.cleanAndExit()
6404
6405 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True ):
6406 """
6407 Compose and return t3-troubleshoot cli command for given source and destination addresses
6408 Options:
6409 sAddr: IP address of the source host
6410 dAddr: IP address of the destination host
6411 """
6412 try:
6413 # Collect information of both hosts from onos
6414 hosts = self.hosts()
6415 hosts = json.loads( hosts )
6416 sHost = None
6417 dHost = None
6418 for host in hosts:
6419 if sAddr in host[ "ipAddresses" ]:
6420 sHost = host
6421 elif dAddr in host[ "ipAddresses" ]:
6422 dHost = host
6423 if sHost and dHost:
6424 break
6425 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang5da39c82018-04-26 22:55:08 -07006426 cmdStr = "t3-troubleshoot"
6427 if verbose:
6428 cmdStr += " -vv"
6429 cmdStr += " -s " + str( sAddr )
6430 # TODO: collect t3 for all locations of source host?
6431 cmdStr += " -sp " + str( sHost[ "locations" ][ 0 ][ "elementId" ] ) + "/" + str( sHost[ "locations" ][ 0 ][ "port" ] )
6432 cmdStr += " -sm " + str( sHost[ "mac" ] )
You Wangc9faf4c2018-05-02 12:05:50 -07006433 if sHost[ "vlan" ] != "None":
6434 cmdStr += " -vid " + sHost[ "vlan" ]
You Wang5da39c82018-04-26 22:55:08 -07006435 cmdStr += " -d " + str( dAddr )
6436 netcfg = self.netcfg( args="devices {}".format( sHost[ "locations" ][ 0 ][ "elementId" ] ) )
6437 netcfg = json.loads( netcfg )
6438 assert netcfg, "Failed to get netcfg"
6439 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6440 if ipv6:
6441 cmdStr += " -et ipv6"
6442 return cmdStr
6443 except AssertionError:
6444 main.log.exception( "" )
6445 return None
6446 except ( KeyError, TypeError ):
6447 main.log.exception( self.name + ": Object not as expected" )
6448 return None
6449 except Exception:
6450 main.log.exception( self.name + ": Uncaught exception!" )
6451 main.cleanAndExit()
6452
6453 def t3( self, sAddr, dAddr, ipv6=False ):
6454 """
6455 Run t3-troubleshoot cli command for given source and destination addresses
6456 Options:
6457 sAddr: IP address of the source host
6458 dAddr: IP address of the destination host
6459 """
6460 try:
6461 cmdStr = self.composeT3Command( sAddr, dAddr, ipv6 )
6462 handle = self.sendline( cmdStr )
6463 assert handle is not None, "Error in sendline"
6464 assert "Command not found:" not in handle, handle
6465 assert "Unsupported command:" not in handle, handle
6466 assert "Error executing command" not in handle, handle
6467 assert "Tracing packet" in handle
6468 return handle
6469 except AssertionError:
6470 main.log.exception( "" )
6471 return None
6472 except pexpect.EOF:
6473 main.log.error( self.name + ": EOF exception found" )
6474 main.log.error( self.name + ": " + self.handle.before )
6475 main.cleanAndExit()
6476 except Exception:
6477 main.log.exception( self.name + ": Uncaught exception!" )
6478 main.cleanAndExit()