blob: 8d2900f0e0aaf96fbb4bcb63115cec5e7aa13063 [file] [log] [blame]
andrewonlab95ce8322014-10-13 14:12:04 -04001#!/usr/bin/env python
2
kelvin8ec71442015-01-15 16:57:00 -08003"""
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07004OCT 13 2014
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005Copyright 2014 Open Networking Foundation (ONF)
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -07006
7Please refer questions to either the onos test mailing list at <onos-test@onosproject.org>,
8the System Testing Plans and Results wiki page at <https://wiki.onosproject.org/x/voMg>,
9or the System Testing Guide page at <https://wiki.onosproject.org/x/WYQg>
10
11 TestON is free software: you can redistribute it and/or modify
12 it under the terms of the GNU General Public License as published by
13 the Free Software Foundation, either version 2 of the License, or
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000014 (at your option) any later version.
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070015
16 TestON is distributed in the hope that it will be useful,
17 but WITHOUT ANY WARRANTY; without even the implied warranty of
18 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 GNU General Public License for more details.
20
21 You should have received a copy of the GNU General Public License
22 along with TestON. If not, see <http://www.gnu.org/licenses/>.
23"""
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +000024
Jeremy Ronquillob27ce4c2017-07-17 12:41:28 -070025"""
andrewonlab95ce8322014-10-13 14:12:04 -040026This driver enters the onos> prompt to issue commands.
27
kelvin8ec71442015-01-15 16:57:00 -080028Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -040029functions and document properly.
30
31If you are a contributor to the driver, please
32list your email here for future contact:
33
34jhall@onlab.us
35andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040036shreya@onlab.us
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +000037jeremyr@opennetworking.org
kelvin8ec71442015-01-15 16:57:00 -080038"""
andrewonlab95ce8322014-10-13 14:12:04 -040039import pexpect
40import re
Jon Hall30b82fa2015-03-04 17:15:43 -080041import json
42import types
Jon Hallbd16b922015-03-26 17:53:15 -070043import time
kelvin-onlaba4074292015-07-09 15:19:49 -070044import os
andrewonlab95ce8322014-10-13 14:12:04 -040045from drivers.common.clidriver import CLI
You Wangdb8cd0a2016-05-26 15:19:45 -070046from core.graph import Graph
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -070047from cStringIO import StringIO
48from itertools import izip
andrewonlab95ce8322014-10-13 14:12:04 -040049
kelvin8ec71442015-01-15 16:57:00 -080050class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040051
kelvin8ec71442015-01-15 16:57:00 -080052 def __init__( self ):
53 """
54 Initialize client
55 """
Jon Hallefbd9792015-03-05 16:11:36 -080056 self.name = None
57 self.home = None
58 self.handle = None
Devin Limdc78e202017-06-09 18:30:07 -070059 self.karafUser = None
60 self.karafPass = None
You Wangdb8cd0a2016-05-26 15:19:45 -070061 self.graph = Graph()
Devin Limdc78e202017-06-09 18:30:07 -070062 super( OnosCliDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080063
Jeremy Ronquillo82705492017-10-18 14:19:55 -070064 def checkOptions( self, var, defaultVar ):
Devin Limdc78e202017-06-09 18:30:07 -070065 if var is None or var == "":
66 return defaultVar
67 return var
Jeremy Ronquillo82705492017-10-18 14:19:55 -070068
kelvin8ec71442015-01-15 16:57:00 -080069 def connect( self, **connectargs ):
70 """
andrewonlab95ce8322014-10-13 14:12:04 -040071 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080072 """
andrewonlab95ce8322014-10-13 14:12:04 -040073 try:
74 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080075 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070076 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040077 for key in self.options:
78 if key == "home":
Devin Limdc78e202017-06-09 18:30:07 -070079 self.home = self.options[ key ]
80 elif key == "karaf_username":
81 self.karafUser = self.options[ key ]
82 elif key == "karaf_password":
83 self.karafPass = self.options[ key ]
84
Jeremy Ronquillo82705492017-10-18 14:19:55 -070085 self.home = self.checkOptions( self.home, "~/onos" )
86 self.karafUser = self.checkOptions( self.karafUser, self.user_name )
87 self.karafPass = self.checkOptions( self.karafPass, self.pwd )
andrewonlab95ce8322014-10-13 14:12:04 -040088
kelvin-onlaba4074292015-07-09 15:19:49 -070089 for key in self.options:
90 if key == 'onosIp':
91 self.onosIp = self.options[ 'onosIp' ]
92 break
93
kelvin8ec71442015-01-15 16:57:00 -080094 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070095
96 try:
Jon Hallc6793552016-01-19 14:18:37 -080097 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070098 self.ip_address = os.getenv( str( self.ip_address ) )
99 else:
100 main.log.info( self.name +
101 ": Trying to connect to " +
102 self.ip_address )
103
104 except KeyError:
105 main.log.info( "Invalid host name," +
106 " connecting to local host instead" )
107 self.ip_address = 'localhost'
108 except Exception as inst:
109 main.log.error( "Uncaught exception: " + str( inst ) )
110
kelvin8ec71442015-01-15 16:57:00 -0800111 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800112 user_name=self.user_name,
113 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800114 port=self.port,
115 pwd=self.pwd,
116 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400117
kelvin8ec71442015-01-15 16:57:00 -0800118 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700119 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400120 if self.handle:
121 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800122 else:
123 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400124 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800125 except TypeError:
126 main.log.exception( self.name + ": Object not as expected" )
127 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400128 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800129 main.log.error( self.name + ": EOF exception found" )
130 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700131 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800132 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800133 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700134 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400135
kelvin8ec71442015-01-15 16:57:00 -0800136 def disconnect( self ):
137 """
andrewonlab95ce8322014-10-13 14:12:04 -0400138 Called when Test is complete to disconnect the ONOS handle.
kelvin8ec71442015-01-15 16:57:00 -0800139 """
Jon Halld61331b2015-02-17 16:35:47 -0800140 response = main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400141 try:
Jon Hall61282e32015-03-19 11:34:11 -0700142 if self.handle:
143 i = self.logout()
144 if i == main.TRUE:
145 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700146 self.handle.expect( self.prompt )
Jon Hall61282e32015-03-19 11:34:11 -0700147 self.handle.sendline( "exit" )
148 self.handle.expect( "closed" )
Jon Halld4d4b372015-01-28 16:02:41 -0800149 except TypeError:
150 main.log.exception( self.name + ": Object not as expected" )
Jon Halld61331b2015-02-17 16:35:47 -0800151 response = main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400152 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800153 main.log.error( self.name + ": EOF exception found" )
154 main.log.error( self.name + ": " + self.handle.before )
Jon Hall61282e32015-03-19 11:34:11 -0700155 except ValueError:
Jon Hall1a77a1e2015-04-06 10:41:13 -0700156 main.log.exception( "Exception in disconnect of " + self.name )
Jon Hall61282e32015-03-19 11:34:11 -0700157 response = main.TRUE
Jon Hallfebb1c72015-03-05 13:30:09 -0800158 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800159 main.log.exception( self.name + ": Connection failed to the host" )
andrewonlab95ce8322014-10-13 14:12:04 -0400160 response = main.FALSE
161 return response
162
kelvin8ec71442015-01-15 16:57:00 -0800163 def logout( self ):
164 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500165 Sends 'logout' command to ONOS cli
Jon Hall61282e32015-03-19 11:34:11 -0700166 Returns main.TRUE if exited CLI and
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000167 main.FALSE on timeout (not guranteed you are disconnected)
Jon Hall61282e32015-03-19 11:34:11 -0700168 None on TypeError
169 Exits test on unknown error or pexpect exits unexpectedly
kelvin8ec71442015-01-15 16:57:00 -0800170 """
andrewonlab38d2b4a2014-11-13 16:28:47 -0500171 try:
Jon Hall61282e32015-03-19 11:34:11 -0700172 if self.handle:
173 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700174 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ],
Jon Hall61282e32015-03-19 11:34:11 -0700175 timeout=10 )
176 if i == 0: # In ONOS CLI
177 self.handle.sendline( "logout" )
Devin Limdc78e202017-06-09 18:30:07 -0700178 j = self.handle.expect( [ self.prompt,
Jon Hallbfe00002016-04-05 10:23:54 -0700179 "Command not found:",
180 pexpect.TIMEOUT ] )
181 if j == 0: # Successfully logged out
182 return main.TRUE
183 elif j == 1 or j == 2:
184 # ONOS didn't fully load, and logout command isn't working
185 # or the command timed out
186 self.handle.send( "\x04" ) # send ctrl-d
Jon Hall64ab3bd2016-05-13 11:29:44 -0700187 try:
Devin Limdc78e202017-06-09 18:30:07 -0700188 self.handle.expect( self.prompt )
Jon Hall64ab3bd2016-05-13 11:29:44 -0700189 except pexpect.TIMEOUT:
190 main.log.error( "ONOS did not respond to 'logout' or CTRL-d" )
Jon Hallbfe00002016-04-05 10:23:54 -0700191 return main.TRUE
Jon Halle0f0b342017-04-18 11:43:47 -0700192 else: # some other output
Jon Hallbfe00002016-04-05 10:23:54 -0700193 main.log.warn( "Unknown repsonse to logout command: '{}'",
194 repr( self.handle.before ) )
195 return main.FALSE
Jon Hall61282e32015-03-19 11:34:11 -0700196 elif i == 1: # not in CLI
197 return main.TRUE
198 elif i == 3: # Timeout
199 return main.FALSE
200 else:
andrewonlab9627f432014-11-14 12:45:10 -0500201 return main.TRUE
Jon Halld4d4b372015-01-28 16:02:41 -0800202 except TypeError:
203 main.log.exception( self.name + ": Object not as expected" )
204 return None
andrewonlab38d2b4a2014-11-13 16:28:47 -0500205 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800206 main.log.error( self.name + ": eof exception found" )
Jon Hall61282e32015-03-19 11:34:11 -0700207 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700208 main.cleanAndExit()
Jon Hall61282e32015-03-19 11:34:11 -0700209 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700210 main.log.error( self.name +
211 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800212 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800213 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700214 main.cleanAndExit()
andrewonlab38d2b4a2014-11-13 16:28:47 -0500215
kelvin-onlabd3b64892015-01-20 13:26:24 -0800216 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800217 """
andrewonlab95ce8322014-10-13 14:12:04 -0400218 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800219
andrewonlab95ce8322014-10-13 14:12:04 -0400220 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800221 """
andrewonlab95ce8322014-10-13 14:12:04 -0400222 try:
223 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800224 main.log.error( "Must define cellname" )
Devin Lim44075962017-08-11 10:56:37 -0700225 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400226 else:
kelvin8ec71442015-01-15 16:57:00 -0800227 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800228 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800229 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400230 # and that this driver will have to change accordingly
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700231 self.handle.expect( str( cellname ) )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800232 handleBefore = self.handle.before
233 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800234 # Get the rest of the handle
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700235 self.handle.sendline( "" )
236 self.handle.expect( self.prompt )
andrew@onlab.usc400b112015-01-21 15:33:19 -0800237 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400238
kelvin-onlabd3b64892015-01-20 13:26:24 -0800239 main.log.info( "Cell call returned: " + handleBefore +
240 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400241
242 return main.TRUE
243
Jon Halld4d4b372015-01-28 16:02:41 -0800244 except TypeError:
245 main.log.exception( self.name + ": Object not as expected" )
246 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400247 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800248 main.log.error( self.name + ": eof exception found" )
249 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700250 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800251 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800252 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700253 main.cleanAndExit()
kelvin8ec71442015-01-15 16:57:00 -0800254
pingping-lin57a56ce2015-05-20 16:43:48 -0700255 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800256 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800257 """
Jon Hallefbd9792015-03-05 16:11:36 -0800258 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800259 by user would be used to set the current karaf shell idle timeout.
260 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800261 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800262 Below is an example to start a session with 60 seconds idle timeout
263 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800264
Hari Krishna25d42f72015-01-05 15:08:28 -0800265 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800266 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800267
kelvin-onlabd3b64892015-01-20 13:26:24 -0800268 Note: karafTimeout is left as str so that this could be read
269 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800270 """
You Wangf69ab392016-01-26 16:34:38 -0800271 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400272 try:
Jon Hall67253832016-12-05 09:47:13 -0800273 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800274 self.handle.sendline( "" )
275 x = self.handle.expect( [
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700276 self.prompt, "onos>" ], commandlineTimeout )
andrewonlab48829f62014-11-17 13:49:01 -0500277 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800278 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500279 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400280
Jon Hall67253832016-12-05 09:47:13 -0800281 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800282 if waitForStart:
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800283 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
284 startCliCommand = "onos-wait-for-start "
Chiyu Chengef109502016-11-21 15:51:38 -0800285 else:
286 startCliCommand = "onos "
287 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800288 i = self.handle.expect( [
289 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700290 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400291
292 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800293 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800294 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800295 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800296 "config:property-set -p org.apache.karaf.shell\
297 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800298 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700299 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800300 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800301 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400302 return main.TRUE
303 else:
kelvin8ec71442015-01-15 16:57:00 -0800304 # If failed, send ctrl+c to process and try again
305 main.log.info( "Starting CLI failed. Retrying..." )
306 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800307 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800308 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
309 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400310 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800311 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800312 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800313 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800314 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800315 "config:property-set -p org.apache.karaf.shell\
316 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800317 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700318 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800319 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800320 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400321 return main.TRUE
322 else:
kelvin8ec71442015-01-15 16:57:00 -0800323 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800324 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400325 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400326
Jon Halld4d4b372015-01-28 16:02:41 -0800327 except TypeError:
328 main.log.exception( self.name + ": Object not as expected" )
329 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400330 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800331 main.log.error( self.name + ": EOF exception found" )
332 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700333 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800334 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800335 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700336 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400337
suibin zhang116647a2016-05-06 16:30:09 -0700338 def startCellCli( self, karafTimeout="",
339 commandlineTimeout=10, onosStartTimeout=60 ):
340 """
341 Start CLI on onos ecll handle.
342
343 karafTimeout is an optional argument. karafTimeout value passed
344 by user would be used to set the current karaf shell idle timeout.
345 Note that when ever this property is modified the shell will exit and
346 the subsequent login would reflect new idle timeout.
347 Below is an example to start a session with 60 seconds idle timeout
348 ( input value is in milliseconds ):
349
350 tValue = "60000"
351
352 Note: karafTimeout is left as str so that this could be read
353 and passed to startOnosCli from PARAMS file as str.
354 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000355
suibin zhang116647a2016-05-06 16:30:09 -0700356 try:
357 self.handle.sendline( "" )
358 x = self.handle.expect( [
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700359 self.prompt, "onos>" ], commandlineTimeout )
suibin zhang116647a2016-05-06 16:30:09 -0700360
361 if x == 1:
362 main.log.info( "ONOS cli is already running" )
363 return main.TRUE
364
Jeremy Ronquilloec916a42018-02-02 13:05:57 -0800365 # Wait for onos start ( onos-wait-for-start ) and enter onos cli
suibin zhang116647a2016-05-06 16:30:09 -0700366 self.handle.sendline( "/opt/onos/bin/onos" )
367 i = self.handle.expect( [
368 "onos>",
369 pexpect.TIMEOUT ], onosStartTimeout )
370
371 if i == 0:
372 main.log.info( self.name + " CLI Started successfully" )
373 if karafTimeout:
374 self.handle.sendline(
375 "config:property-set -p org.apache.karaf.shell\
376 sshIdleTimeout " +
377 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700378 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700379 self.handle.sendline( "/opt/onos/bin/onos" )
380 self.handle.expect( "onos>" )
381 return main.TRUE
382 else:
383 # If failed, send ctrl+c to process and try again
384 main.log.info( "Starting CLI failed. Retrying..." )
385 self.handle.send( "\x03" )
386 self.handle.sendline( "/opt/onos/bin/onos" )
387 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
388 timeout=30 )
389 if i == 0:
390 main.log.info( self.name + " CLI Started " +
391 "successfully after retry attempt" )
392 if karafTimeout:
393 self.handle.sendline(
394 "config:property-set -p org.apache.karaf.shell\
395 sshIdleTimeout " +
396 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700397 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700398 self.handle.sendline( "/opt/onos/bin/onos" )
399 self.handle.expect( "onos>" )
400 return main.TRUE
401 else:
402 main.log.error( "Connection to CLI " +
403 self.name + " timeout" )
404 return main.FALSE
405
406 except TypeError:
407 main.log.exception( self.name + ": Object not as expected" )
408 return None
409 except pexpect.EOF:
410 main.log.error( self.name + ": EOF exception found" )
411 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700412 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700413 except Exception:
414 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700415 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700416
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800417 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800418 """
419 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800420 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800421 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700422 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800423 Available level: DEBUG, TRACE, INFO, WARN, ERROR
424 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800425 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800426 """
427 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800428 lvlStr = ""
429 if level:
430 lvlStr = "--level=" + level
431
kelvin-onlab338f5512015-02-06 10:53:16 -0800432 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700433 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800434 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800435
kelvin-onlab9f541032015-02-04 16:19:53 -0800436 response = self.handle.before
437 if re.search( "Error", response ):
438 return main.FALSE
439 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700440 except pexpect.TIMEOUT:
441 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700442 if noExit:
443 main.cleanup()
444 return None
445 else:
Devin Lim44075962017-08-11 10:56:37 -0700446 main.cleanAndExit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800447 except pexpect.EOF:
448 main.log.error( self.name + ": EOF exception found" )
449 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700450 if noExit:
451 main.cleanup()
452 return None
453 else:
Devin Lim44075962017-08-11 10:56:37 -0700454 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800455 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800456 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700457 if noExit:
458 main.cleanup()
459 return None
460 else:
Devin Lim44075962017-08-11 10:56:37 -0700461 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400462
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700463 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, dollarSign=False ):
kelvin8ec71442015-01-15 16:57:00 -0800464 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800465 Send a completely user specified string to
466 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400467 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800468
YPZhang14a4aa92016-07-15 13:37:15 -0700469 if noExit is True, TestON will not exit, and return None
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700470 if dollarSign is True, TestON will not expect for '$' as a new CLI or onos> prompt
471 since '$' can be in the output.
YPZhangebf9eb52016-05-12 15:20:24 -0700472
andrewonlaba18f6bf2014-10-13 19:31:54 -0400473 Warning: There are no sanity checking to commands
474 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800475
kelvin8ec71442015-01-15 16:57:00 -0800476 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400477 try:
Jon Halla495f562016-05-16 18:03:26 -0700478 # Try to reconnect if disconnected from cli
479 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700480 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ] )
Jon Halla495f562016-05-16 18:03:26 -0700481 if i == 1:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700482 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700483 if self.onosIp:
484 main.log.warn( "Trying to reconnect " + self.onosIp )
485 reconnectResult = self.startOnosCli( self.onosIp )
486 if reconnectResult:
487 main.log.info( self.name + ": onos cli session reconnected." )
488 else:
489 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700490 if noExit:
491 return None
492 else:
Devin Lim44075962017-08-11 10:56:37 -0700493 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700494 else:
Devin Lim44075962017-08-11 10:56:37 -0700495 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700496 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700497 main.log.warn( "Timeout when testing cli responsiveness" )
498 main.log.debug( self.handle.before )
499 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700500 self.handle.expect( "onos>" )
501
Jon Hall14a03b52016-05-11 12:07:30 -0700502 if debug:
503 # NOTE: This adds and average of .4 seconds per call
504 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700505 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800506 self.handle.sendline( cmdStr )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700507 if dollarSign:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700508 i = self.handle.expect( [ "onos>" ], timeout )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700509 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700510 i = self.handle.expect( [ "onos>", self.prompt ], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800511 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800512 # TODO: do something with i
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000513 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800514 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700515 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700516 main.log.debug( self.name + ": Raw output" )
517 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700518
519 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800520 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800521 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700522 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700523 main.log.debug( self.name + ": ansiEscape output" )
524 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700525
kelvin-onlabfb521662015-02-27 09:52:40 -0800526 # Remove extra return chars that get added
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000527 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700528 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700529 main.log.debug( self.name + ": Removed extra returns " +
530 "from output" )
531 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700532
533 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800534 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700535 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700536 main.log.debug( self.name + ": parsed and stripped output" )
537 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700538
Jon Hall63604932015-02-26 17:09:50 -0800539 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700540 output = response.split( cmdStr.strip(), 1 )
541 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700542 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700543 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700544 main.log.debug( self.name + ": " + repr( r ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700545 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800546 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800547 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800548 return output
GlennRCed771242016-01-13 17:02:47 -0800549 except pexpect.TIMEOUT:
550 main.log.error( self.name + ":ONOS timeout" )
551 if debug:
552 main.log.debug( self.handle.before )
553 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700554 except IndexError:
555 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700556 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700557 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800558 except TypeError:
559 main.log.exception( self.name + ": Object not as expected" )
560 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400561 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800562 main.log.error( self.name + ": EOF exception found" )
563 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700564 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700565 return None
566 else:
Devin Lim44075962017-08-11 10:56:37 -0700567 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800568 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800569 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700570 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700571 return None
572 else:
Devin Lim44075962017-08-11 10:56:37 -0700573 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400574
kelvin8ec71442015-01-15 16:57:00 -0800575 # IMPORTANT NOTE:
576 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800577 # the cli command changing 'a:b' with 'aB'.
578 # Ex ) onos:topology > onosTopology
579 # onos:links > onosLinks
580 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800581
kelvin-onlabd3b64892015-01-20 13:26:24 -0800582 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800583 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400584 Adds a new cluster node by ID and address information.
585 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800586 * nodeId
587 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400588 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800589 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800590 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400591 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800592 cmdStr = "add-node " + str( nodeId ) + " " +\
593 str( ONOSIp ) + " " + str( tcpPort )
594 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700595 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800596 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800597 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800598 main.log.error( "Error in adding node" )
599 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800600 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400601 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400603 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800604 except AssertionError:
605 main.log.exception( "" )
606 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800607 except TypeError:
608 main.log.exception( self.name + ": Object not as expected" )
609 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400610 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800611 main.log.error( self.name + ": EOF exception found" )
612 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700613 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800614 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800615 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700616 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400617
kelvin-onlabd3b64892015-01-20 13:26:24 -0800618 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800619 """
andrewonlab86dc3082014-10-13 18:18:38 -0400620 Removes a cluster by ID
621 Issues command: 'remove-node [<node-id>]'
622 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800623 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800624 """
andrewonlab86dc3082014-10-13 18:18:38 -0400625 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400626
kelvin-onlabd3b64892015-01-20 13:26:24 -0800627 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700628 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700629 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800630 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700631 if re.search( "Error", handle ):
632 main.log.error( "Error in removing node" )
633 main.log.error( handle )
634 return main.FALSE
635 else:
636 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800637 except AssertionError:
638 main.log.exception( "" )
639 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800640 except TypeError:
641 main.log.exception( self.name + ": Object not as expected" )
642 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400643 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800644 main.log.error( self.name + ": EOF exception found" )
645 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700646 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800647 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800648 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700649 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400650
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700651 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800652 """
andrewonlab7c211572014-10-15 16:45:20 -0400653 List the nodes currently visible
654 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700655 Optional argument:
656 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800657 """
andrewonlab7c211572014-10-15 16:45:20 -0400658 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700659 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700660 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700661 cmdStr += " -j"
662 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700663 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800664 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700665 return output
Jon Hallc6793552016-01-19 14:18:37 -0800666 except AssertionError:
667 main.log.exception( "" )
668 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800669 except TypeError:
670 main.log.exception( self.name + ": Object not as expected" )
671 return None
andrewonlab7c211572014-10-15 16:45:20 -0400672 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800673 main.log.error( self.name + ": EOF exception found" )
674 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700675 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800676 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800677 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700678 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400679
kelvin8ec71442015-01-15 16:57:00 -0800680 def topology( self ):
681 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700682 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700683 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700684 Return:
685 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800686 """
andrewonlab95ce8322014-10-13 14:12:04 -0400687 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700688 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800689 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800690 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800691 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700692 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400693 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800694 except AssertionError:
695 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800696 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800697 except TypeError:
698 main.log.exception( self.name + ": Object not as expected" )
699 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400700 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800701 main.log.error( self.name + ": EOF exception found" )
702 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700703 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800704 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800705 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700706 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800707
jenkins7ead5a82015-03-13 10:28:21 -0700708 def deviceRemove( self, deviceId ):
709 """
710 Removes particular device from storage
711
712 TODO: refactor this function
713 """
714 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700715 cmdStr = "device-remove " + str( deviceId )
716 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800717 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800718 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700719 if re.search( "Error", handle ):
720 main.log.error( "Error in removing device" )
721 main.log.error( handle )
722 return main.FALSE
723 else:
724 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800725 except AssertionError:
726 main.log.exception( "" )
727 return None
jenkins7ead5a82015-03-13 10:28:21 -0700728 except TypeError:
729 main.log.exception( self.name + ": Object not as expected" )
730 return None
731 except pexpect.EOF:
732 main.log.error( self.name + ": EOF exception found" )
733 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700734 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700735 except Exception:
736 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700737 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700738
kelvin-onlabd3b64892015-01-20 13:26:24 -0800739 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800740 """
Jon Hall7b02d952014-10-17 20:14:54 -0400741 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400742 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800743 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800744 """
andrewonlab86dc3082014-10-13 18:18:38 -0400745 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700746 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800747 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700748 cmdStr += " -j"
749 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800750 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800751 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700752 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800753 except AssertionError:
754 main.log.exception( "" )
755 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800756 except TypeError:
757 main.log.exception( self.name + ": Object not as expected" )
758 return None
andrewonlab7c211572014-10-15 16:45:20 -0400759 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800760 main.log.error( self.name + ": EOF exception found" )
761 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700762 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800763 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800764 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700765 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400766
kelvin-onlabd3b64892015-01-20 13:26:24 -0800767 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800768 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800769 This balances the devices across all controllers
770 by issuing command: 'onos> onos:balance-masters'
771 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800772 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800773 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800774 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700775 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800776 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800777 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700778 if re.search( "Error", handle ):
779 main.log.error( "Error in balancing masters" )
780 main.log.error( handle )
781 return main.FALSE
782 else:
783 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800784 except AssertionError:
785 main.log.exception( "" )
786 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800787 except TypeError:
788 main.log.exception( self.name + ": Object not as expected" )
789 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800790 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800791 main.log.error( self.name + ": EOF exception found" )
792 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700793 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800794 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800795 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700796 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800797
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +0000798 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700799 """
800 Returns the output of the masters command.
801 Optional argument:
802 * jsonFormat - boolean indicating if you want output in json
803 """
804 try:
805 cmdStr = "onos:masters"
806 if jsonFormat:
807 cmdStr += " -j"
808 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700809 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800810 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700811 return output
Jon Hallc6793552016-01-19 14:18:37 -0800812 except AssertionError:
813 main.log.exception( "" )
814 return None
acsmars24950022015-07-30 18:00:43 -0700815 except TypeError:
816 main.log.exception( self.name + ": Object not as expected" )
817 return None
818 except pexpect.EOF:
819 main.log.error( self.name + ": EOF exception found" )
820 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700821 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700822 except Exception:
823 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700824 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700825
Jon Hallc6793552016-01-19 14:18:37 -0800826 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700827 """
828 Uses the master command to check that the devices' leadership
829 is evenly divided
830
831 Dependencies: checkMasters() and summary()
832
Jon Hall6509dbf2016-06-21 17:01:17 -0700833 Returns main.TRUE if the devices are balanced
834 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700835 Exits on Exception
836 Returns None on TypeError
837 """
838 try:
Jon Hallc6793552016-01-19 14:18:37 -0800839 summaryOutput = self.summary()
840 totalDevices = json.loads( summaryOutput )[ "devices" ]
841 except ( TypeError, ValueError ):
842 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
843 return None
844 try:
acsmars24950022015-07-30 18:00:43 -0700845 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800846 mastersOutput = self.checkMasters()
847 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700848 first = masters[ 0 ][ "size" ]
849 for master in masters:
850 totalOwnedDevices += master[ "size" ]
851 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
852 main.log.error( "Mastership not balanced" )
853 main.log.info( "\n" + self.checkMasters( False ) )
854 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700855 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -0700856 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700857 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800858 except ( TypeError, ValueError ):
859 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700860 return None
861 except pexpect.EOF:
862 main.log.error( self.name + ": EOF exception found" )
863 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700864 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700865 except Exception:
866 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700867 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700868
YPZhangfebf7302016-05-24 16:45:56 -0700869 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800870 """
Jon Halle8217482014-10-17 13:49:14 -0400871 Lists all core links
872 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800873 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800874 """
Jon Halle8217482014-10-17 13:49:14 -0400875 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700876 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800877 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700878 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700879 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800880 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800881 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700882 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800883 except AssertionError:
884 main.log.exception( "" )
885 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800886 except TypeError:
887 main.log.exception( self.name + ": Object not as expected" )
888 return None
Jon Halle8217482014-10-17 13:49:14 -0400889 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800890 main.log.error( self.name + ": EOF exception found" )
891 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700892 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800893 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800894 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700895 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400896
kelvin-onlabd3b64892015-01-20 13:26:24 -0800897 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800898 """
Jon Halle8217482014-10-17 13:49:14 -0400899 Lists all ports
900 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800901 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800902 """
Jon Halle8217482014-10-17 13:49:14 -0400903 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700904 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800905 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700906 cmdStr += " -j"
907 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800908 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800909 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700910 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800911 except AssertionError:
912 main.log.exception( "" )
913 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800914 except TypeError:
915 main.log.exception( self.name + ": Object not as expected" )
916 return None
Jon Halle8217482014-10-17 13:49:14 -0400917 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800918 main.log.error( self.name + ": EOF exception found" )
919 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700920 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800921 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800922 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700923 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400924
kelvin-onlabd3b64892015-01-20 13:26:24 -0800925 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800926 """
Jon Hall983a1702014-10-28 18:44:22 -0400927 Lists all devices and the controllers with roles assigned to them
928 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800929 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800930 """
andrewonlab7c211572014-10-15 16:45:20 -0400931 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700932 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800933 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700934 cmdStr += " -j"
935 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800936 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800937 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700938 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800939 except AssertionError:
940 main.log.exception( "" )
941 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800942 except TypeError:
943 main.log.exception( self.name + ": Object not as expected" )
944 return None
Jon Hall983a1702014-10-28 18:44:22 -0400945 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800946 main.log.error( self.name + ": EOF exception found" )
947 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700948 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800949 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800950 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700951 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -0400952
kelvin-onlabd3b64892015-01-20 13:26:24 -0800953 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800954 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800955 Given the a string containing the json representation of the "roles"
956 cli command and a partial or whole device id, returns a json object
957 containing the roles output for the first device whose id contains
958 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400959
960 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800961 A dict of the role assignments for the given device or
962 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800963 """
Jon Hall983a1702014-10-28 18:44:22 -0400964 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800965 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400966 return None
967 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800968 rawRoles = self.roles()
969 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800970 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800972 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800973 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400974 return device
975 return None
Jon Hallc6793552016-01-19 14:18:37 -0800976 except ( TypeError, ValueError ):
977 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800978 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400979 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800980 main.log.error( self.name + ": EOF exception found" )
981 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700982 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800983 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800984 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700985 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -0800986
kelvin-onlabd3b64892015-01-20 13:26:24 -0800987 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800988 """
Jon Hall94fd0472014-12-08 11:52:42 -0800989 Iterates through each device and checks if there is a master assigned
990 Returns: main.TRUE if each device has a master
991 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800992 """
Jon Hall94fd0472014-12-08 11:52:42 -0800993 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800994 rawRoles = self.roles()
995 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800996 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800997 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800998 # print device
999 if device[ 'master' ] == "none":
1000 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001001 return main.FALSE
1002 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001003 except ( TypeError, ValueError ):
1004 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001005 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001006 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001007 main.log.error( self.name + ": EOF exception found" )
1008 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001009 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001010 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001011 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001012 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001013
kelvin-onlabd3b64892015-01-20 13:26:24 -08001014 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001015 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001016 Returns string of paths, and the cost.
1017 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001018 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001019 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001020 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1021 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001022 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001023 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001024 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001025 main.log.error( "Error in getting paths" )
1026 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001027 else:
kelvin8ec71442015-01-15 16:57:00 -08001028 path = handle.split( ";" )[ 0 ]
1029 cost = handle.split( ";" )[ 1 ]
1030 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001031 except AssertionError:
1032 main.log.exception( "" )
1033 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001034 except TypeError:
1035 main.log.exception( self.name + ": Object not as expected" )
1036 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001037 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001038 main.log.error( self.name + ": EOF exception found" )
1039 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001040 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001041 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001042 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001043 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001044
kelvin-onlabd3b64892015-01-20 13:26:24 -08001045 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001046 """
Jon Hallffb386d2014-11-21 13:43:38 -08001047 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001048 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001049 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001050 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001051 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001052 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001053 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001054 cmdStr += " -j"
1055 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001056 if handle:
1057 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001058 # TODO: Maybe make this less hardcoded
1059 # ConsistentMap Exceptions
1060 assert "org.onosproject.store.service" not in handle
1061 # Node not leader
1062 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001063 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001064 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001065 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001066 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001067 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001068 except TypeError:
1069 main.log.exception( self.name + ": Object not as expected" )
1070 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001071 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001072 main.log.error( self.name + ": EOF exception found" )
1073 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001074 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001075 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001076 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001077 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001078
kelvin-onlabd3b64892015-01-20 13:26:24 -08001079 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001080 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001081 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001082
Jon Hallefbd9792015-03-05 16:11:36 -08001083 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001084 partial mac address
1085
Jon Hall42db6dc2014-10-24 19:03:48 -04001086 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001087 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001088 try:
kelvin8ec71442015-01-15 16:57:00 -08001089 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001090 return None
1091 else:
1092 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001093 rawHosts = self.hosts()
1094 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001095 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001096 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001097 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001098 if not host:
1099 pass
1100 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001101 return host
1102 return None
Jon Hallc6793552016-01-19 14:18:37 -08001103 except ( TypeError, ValueError ):
1104 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001105 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001106 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001107 main.log.error( self.name + ": EOF exception found" )
1108 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001109 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001110 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001111 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001112 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001113
kelvin-onlabd3b64892015-01-20 13:26:24 -08001114 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001115 """
1116 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001117 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001118
andrewonlab3f0a4af2014-10-17 12:25:14 -04001119 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001120 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001121 IMPORTANT:
1122 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001123 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001124 Furthermore, it assumes that value of VLAN is '-1'
1125 Description:
kelvin8ec71442015-01-15 16:57:00 -08001126 Converts mininet hosts ( h1, h2, h3... ) into
1127 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1128 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001129 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001130 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001131
kelvin-onlabd3b64892015-01-20 13:26:24 -08001132 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001133 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001134 hostHex = hex( int( host ) ).zfill( 12 )
1135 hostHex = str( hostHex ).replace( 'x', '0' )
1136 i = iter( str( hostHex ) )
1137 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1138 hostHex = hostHex + "/-1"
1139 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001140
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001142
Jon Halld4d4b372015-01-28 16:02:41 -08001143 except TypeError:
1144 main.log.exception( self.name + ": Object not as expected" )
1145 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001146 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001147 main.log.error( self.name + ": EOF exception found" )
1148 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001149 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001150 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001151 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001152 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001153
You Wangbc898b82018-05-03 16:22:34 -07001154 def verifyHostLocation( self, hostIp, location ):
1155 """
1156 Description:
1157 Verify the host given is discovered in all locations expected
1158 Required:
1159 hostIp: IP address of the host
1160 location: expected location(s) of the given host. ex. "of:0000000000000005/8"
1161 Could be a string or list
1162 Returns:
1163 main.TRUE if host is discovered on all locations provided
1164 main.FALSE otherwise
1165 """
1166 import json
1167 locations = [ location ] if isinstance( location, str ) else location
1168 assert isinstance( locations, list ), "Wrong type of location: {}".format( type( location ) )
1169 try:
1170 hosts = self.hosts()
1171 hosts = json.loads( hosts )
1172 targetHost = None
1173 for host in hosts:
1174 if hostIp in host[ "ipAddresses" ]:
1175 targetHost = host
You Wangfd80ab42018-05-10 17:21:53 -07001176 assert targetHost, "Not able to find host with IP {}".format( hostIp )
You Wangbc898b82018-05-03 16:22:34 -07001177 result = main.TRUE
1178 locationsDiscovered = [ loc[ "elementId" ] + "/" + loc[ "port" ] for loc in targetHost[ "locations" ] ]
1179 for loc in locations:
1180 discovered = False
1181 for locDiscovered in locationsDiscovered:
You Wang547893e2018-05-08 13:34:59 -07001182 locToMatch = locDiscovered if "/" in loc else locDiscovered.split( "/" )[0]
1183 if loc == locToMatch:
You Wangbc898b82018-05-03 16:22:34 -07001184 main.log.debug( "Host {} discovered with location {}".format( hostIp, loc ) )
You Wang547893e2018-05-08 13:34:59 -07001185 discovered = True
You Wangbc898b82018-05-03 16:22:34 -07001186 break
1187 if discovered:
1188 locationsDiscovered.remove( locDiscovered )
1189 else:
1190 main.log.warn( "Host {} not discovered with location {}".format( hostIp, loc ) )
1191 result = main.FALSE
1192 if locationsDiscovered:
1193 main.log.warn( "Host {} is also discovered with location {}".format( hostIp, locationsDiscovered ) )
1194 result = main.FALSE
1195 return result
1196 except KeyError:
1197 main.log.exception( self.name + ": host data not as expected: " + hosts )
1198 return None
1199 except pexpect.EOF:
1200 main.log.error( self.name + ": EOF exception found" )
1201 main.log.error( self.name + ": " + self.handle.before )
1202 main.cleanAndExit()
1203 except Exception:
1204 main.log.exception( self.name + ": Uncaught exception" )
1205 return None
1206
You Wang53dba1e2018-02-02 17:45:44 -08001207 def verifyHostIp( self, hostList=[], prefix="" ):
1208 """
1209 Description:
1210 Verify that all hosts have IP address assigned to them
1211 Optional:
1212 hostList: If specified, verifications only happen to the hosts
1213 in hostList
1214 prefix: at least one of the ip address assigned to the host
1215 needs to have the specified prefix
1216 Returns:
1217 main.TRUE if all hosts have specific IP address assigned;
1218 main.FALSE otherwise
1219 """
1220 import json
1221 try:
1222 hosts = self.hosts()
1223 hosts = json.loads( hosts )
1224 if not hostList:
1225 hostList = [ host[ "id" ] for host in hosts ]
1226 for host in hosts:
1227 hostId = host[ "id" ]
1228 if hostId not in hostList:
1229 continue
1230 ipList = host[ "ipAddresses" ]
1231 main.log.debug( self.name + ": IP list on host " + str( hostId ) + ": " + str( ipList ) )
1232 if not ipList:
1233 main.log.warn( self.name + ": Failed to discover any IP addresses on host " + str( hostId ) )
1234 else:
1235 if not any( ip.startswith( str( prefix ) ) for ip in ipList ):
1236 main.log.warn( self.name + ": None of the IPs on host " + str( hostId ) + " has prefix " + str( prefix ) )
1237 else:
1238 main.log.debug( self.name + ": Found matching IP on host " + str( hostId ) )
1239 hostList.remove( hostId )
1240 if hostList:
1241 main.log.warn( self.name + ": failed to verify IP on following hosts: " + str( hostList) )
1242 return main.FALSE
1243 else:
1244 return main.TRUE
1245 except KeyError:
1246 main.log.exception( self.name + ": host data not as expected: " + hosts )
1247 return None
1248 except pexpect.EOF:
1249 main.log.error( self.name + ": EOF exception found" )
1250 main.log.error( self.name + ": " + self.handle.before )
1251 main.cleanAndExit()
1252 except Exception:
1253 main.log.exception( self.name + ": Uncaught exception" )
1254 return None
1255
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001256 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001257 """
andrewonlabe6745342014-10-17 14:29:13 -04001258 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 * hostIdOne: ONOS host id for host1
1260 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001261 Optional:
1262 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001263 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001264 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001265 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001266 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001267 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001268 Returns:
1269 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001270 """
andrewonlabe6745342014-10-17 14:29:13 -04001271 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001272 cmdStr = "add-host-intent "
1273 if vlanId:
1274 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001275 if setVlan:
1276 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001277 if encap:
1278 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001279 if bandwidth:
1280 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001281 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001282 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001283 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001284 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001285 if re.search( "Error", handle ):
1286 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001287 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001288 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001289 else:
1290 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001291 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001292 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001293 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001294 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001295 else:
1296 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001297 main.log.debug( "Response from ONOS was: " +
1298 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001299 return None
Jon Hallc6793552016-01-19 14:18:37 -08001300 except AssertionError:
1301 main.log.exception( "" )
1302 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001303 except TypeError:
1304 main.log.exception( self.name + ": Object not as expected" )
1305 return None
andrewonlabe6745342014-10-17 14:29:13 -04001306 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001307 main.log.error( self.name + ": EOF exception found" )
1308 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001309 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001310 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001311 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001312 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001313
kelvin-onlabd3b64892015-01-20 13:26:24 -08001314 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001315 """
andrewonlab7b31d232014-10-24 13:31:47 -04001316 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001317 * ingressDevice: device id of ingress device
1318 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001319 Optional:
1320 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001321 Description:
1322 Adds an optical intent by specifying an ingress and egress device
1323 Returns:
1324 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001325 """
andrewonlab7b31d232014-10-24 13:31:47 -04001326 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001327 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1328 " " + str( egressDevice )
1329 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001330 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001331 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001332 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001333 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001334 main.log.error( "Error in adding Optical intent" )
1335 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001336 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001337 main.log.info( "Optical intent installed between " +
1338 str( ingressDevice ) + " and " +
1339 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001340 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001341 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001342 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001343 else:
1344 main.log.error( "Error, intent ID not found" )
1345 return None
Jon Hallc6793552016-01-19 14:18:37 -08001346 except AssertionError:
1347 main.log.exception( "" )
1348 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001349 except TypeError:
1350 main.log.exception( self.name + ": Object not as expected" )
1351 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001352 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001353 main.log.error( self.name + ": EOF exception found" )
1354 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001355 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001356 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001357 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001358 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001359
kelvin-onlabd3b64892015-01-20 13:26:24 -08001360 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001361 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001362 ingressDevice,
1363 egressDevice,
1364 portIngress="",
1365 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001366 ethType="",
1367 ethSrc="",
1368 ethDst="",
1369 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001370 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001371 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001372 ipProto="",
1373 ipSrc="",
1374 ipDst="",
1375 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001376 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001377 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001378 setVlan="",
1379 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001380 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001381 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001382 * ingressDevice: device id of ingress device
1383 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001384 Optional:
1385 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001386 * ethSrc: specify ethSrc ( i.e. src mac addr )
1387 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001388 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001389 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001390 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001391 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001392 * ipSrc: specify ip source address
1393 * ipDst: specify ip destination address
1394 * tcpSrc: specify tcp source port
1395 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001396 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001397 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001398 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001399 Description:
kelvin8ec71442015-01-15 16:57:00 -08001400 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001401 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001402 Returns:
1403 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001404
Jon Halle3f39ff2015-01-13 11:50:53 -08001405 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001406 options developers provide for point-to-point
1407 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001408 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001409 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001410 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001411
Jeremy Songsterff553672016-05-12 17:06:23 -07001412 if ethType:
1413 cmd += " --ethType " + str( ethType )
1414 if ethSrc:
1415 cmd += " --ethSrc " + str( ethSrc )
1416 if ethDst:
1417 cmd += " --ethDst " + str( ethDst )
1418 if bandwidth:
1419 cmd += " --bandwidth " + str( bandwidth )
1420 if lambdaAlloc:
1421 cmd += " --lambda "
1422 if ipProto:
1423 cmd += " --ipProto " + str( ipProto )
1424 if ipSrc:
1425 cmd += " --ipSrc " + str( ipSrc )
1426 if ipDst:
1427 cmd += " --ipDst " + str( ipDst )
1428 if tcpSrc:
1429 cmd += " --tcpSrc " + str( tcpSrc )
1430 if tcpDst:
1431 cmd += " --tcpDst " + str( tcpDst )
1432 if vlanId:
1433 cmd += " -v " + str( vlanId )
1434 if setVlan:
1435 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001436 if encap:
1437 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001438 if protected:
1439 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001440
kelvin8ec71442015-01-15 16:57:00 -08001441 # Check whether the user appended the port
1442 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001443 if "/" in ingressDevice:
1444 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001445 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001446 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001447 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001448 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001449 # Would it make sense to throw an exception and exit
1450 # the test?
1451 return None
andrewonlab36af3822014-11-18 17:48:18 -05001452
kelvin8ec71442015-01-15 16:57:00 -08001453 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001454 str( ingressDevice ) + "/" +\
1455 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001456
kelvin-onlabd3b64892015-01-20 13:26:24 -08001457 if "/" in egressDevice:
1458 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001459 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001460 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001461 main.log.error( "You must specify the egress port" )
1462 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001463
kelvin8ec71442015-01-15 16:57:00 -08001464 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001465 str( egressDevice ) + "/" +\
1466 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001467
kelvin-onlab898a6c62015-01-16 14:13:53 -08001468 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001469 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001470 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001471 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001472 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001473 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001474 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001475 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001476 # TODO: print out all the options in this message?
1477 main.log.info( "Point-to-point intent installed between " +
1478 str( ingressDevice ) + " and " +
1479 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001480 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001481 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001482 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001483 else:
1484 main.log.error( "Error, intent ID not found" )
1485 return None
Jon Hallc6793552016-01-19 14:18:37 -08001486 except AssertionError:
1487 main.log.exception( "" )
1488 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001489 except TypeError:
1490 main.log.exception( self.name + ": Object not as expected" )
1491 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001492 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001493 main.log.error( self.name + ": EOF exception found" )
1494 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001495 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001496 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001497 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001498 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001499
kelvin-onlabd3b64892015-01-20 13:26:24 -08001500 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001501 self,
shahshreyac2f97072015-03-19 17:04:29 -07001502 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001503 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001504 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001505 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001506 ethType="",
1507 ethSrc="",
1508 ethDst="",
1509 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001510 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001511 ipProto="",
1512 ipSrc="",
1513 ipDst="",
1514 tcpSrc="",
1515 tcpDst="",
1516 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001517 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001518 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001519 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001520 partial=False,
1521 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001522 """
shahshreyad0c80432014-12-04 16:56:05 -08001523 Note:
shahshreya70622b12015-03-19 17:19:00 -07001524 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001525 is same. That is, all ingress devices include port numbers
1526 with a "/" or all ingress devices could specify device
1527 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001528 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001529 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001530 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001531 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001532 Optional:
1533 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001534 * ethSrc: specify ethSrc ( i.e. src mac addr )
1535 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001536 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001537 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001538 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001539 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001540 * ipSrc: specify ip source address
1541 * ipDst: specify ip destination address
1542 * tcpSrc: specify tcp source port
1543 * tcpDst: specify tcp destination port
1544 * setEthSrc: action to Rewrite Source MAC Address
1545 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001546 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001547 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001548 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001549 Description:
kelvin8ec71442015-01-15 16:57:00 -08001550 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001551 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001552 Returns:
1553 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001554
Jon Halle3f39ff2015-01-13 11:50:53 -08001555 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001556 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001557 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001558 """
shahshreyad0c80432014-12-04 16:56:05 -08001559 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001560 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001561
Jeremy Songsterff553672016-05-12 17:06:23 -07001562 if ethType:
1563 cmd += " --ethType " + str( ethType )
1564 if ethSrc:
1565 cmd += " --ethSrc " + str( ethSrc )
1566 if ethDst:
1567 cmd += " --ethDst " + str( ethDst )
1568 if bandwidth:
1569 cmd += " --bandwidth " + str( bandwidth )
1570 if lambdaAlloc:
1571 cmd += " --lambda "
1572 if ipProto:
1573 cmd += " --ipProto " + str( ipProto )
1574 if ipSrc:
1575 cmd += " --ipSrc " + str( ipSrc )
1576 if ipDst:
1577 cmd += " --ipDst " + str( ipDst )
1578 if tcpSrc:
1579 cmd += " --tcpSrc " + str( tcpSrc )
1580 if tcpDst:
1581 cmd += " --tcpDst " + str( tcpDst )
1582 if setEthSrc:
1583 cmd += " --setEthSrc " + str( setEthSrc )
1584 if setEthDst:
1585 cmd += " --setEthDst " + str( setEthDst )
1586 if vlanId:
1587 cmd += " -v " + str( vlanId )
1588 if setVlan:
1589 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001590 if partial:
1591 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001592 if encap:
1593 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001594
kelvin8ec71442015-01-15 16:57:00 -08001595 # Check whether the user appended the port
1596 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001597
1598 if portIngressList is None:
1599 for ingressDevice in ingressDeviceList:
1600 if "/" in ingressDevice:
1601 cmd += " " + str( ingressDevice )
1602 else:
1603 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001604 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001605 # TODO: perhaps more meaningful return
1606 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001607 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001608 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001609 for ingressDevice, portIngress in zip( ingressDeviceList,
1610 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001611 cmd += " " + \
1612 str( ingressDevice ) + "/" +\
1613 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001614 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001615 main.log.error( "Device list and port list does not " +
1616 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001617 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001618 if "/" in egressDevice:
1619 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001620 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001621 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001622 main.log.error( "You must specify " +
1623 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001624 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001625
kelvin8ec71442015-01-15 16:57:00 -08001626 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001627 str( egressDevice ) + "/" +\
1628 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001629 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001630 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001631 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001632 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001633 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001634 main.log.error( "Error in adding multipoint-to-singlepoint " +
1635 "intent" )
1636 return None
shahshreyad0c80432014-12-04 16:56:05 -08001637 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001638 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001639 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001640 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001641 else:
1642 main.log.error( "Error, intent ID not found" )
1643 return None
Jon Hallc6793552016-01-19 14:18:37 -08001644 except AssertionError:
1645 main.log.exception( "" )
1646 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001647 except TypeError:
1648 main.log.exception( self.name + ": Object not as expected" )
1649 return None
1650 except pexpect.EOF:
1651 main.log.error( self.name + ": EOF exception found" )
1652 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001653 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001654 except Exception:
1655 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001656 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001657
1658 def addSinglepointToMultipointIntent(
1659 self,
1660 ingressDevice,
1661 egressDeviceList,
1662 portIngress="",
1663 portEgressList=None,
1664 ethType="",
1665 ethSrc="",
1666 ethDst="",
1667 bandwidth="",
1668 lambdaAlloc=False,
1669 ipProto="",
1670 ipSrc="",
1671 ipDst="",
1672 tcpSrc="",
1673 tcpDst="",
1674 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001675 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001676 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001677 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001678 partial=False,
1679 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001680 """
1681 Note:
1682 This function assumes the format of all egress devices
1683 is same. That is, all egress devices include port numbers
1684 with a "/" or all egress devices could specify device
1685 ids and port numbers seperately.
1686 Required:
1687 * EgressDeviceList: List of device ids of egress device
1688 ( Atleast 2 eress devices required in the list )
1689 * ingressDevice: device id of ingress device
1690 Optional:
1691 * ethType: specify ethType
1692 * ethSrc: specify ethSrc ( i.e. src mac addr )
1693 * ethDst: specify ethDst ( i.e. dst mac addr )
1694 * bandwidth: specify bandwidth capacity of link
1695 * lambdaAlloc: if True, intent will allocate lambda
1696 for the specified intent
1697 * ipProto: specify ip protocol
1698 * ipSrc: specify ip source address
1699 * ipDst: specify ip destination address
1700 * tcpSrc: specify tcp source port
1701 * tcpDst: specify tcp destination port
1702 * setEthSrc: action to Rewrite Source MAC Address
1703 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001704 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001705 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001706 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001707 Description:
1708 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1709 specifying device id's and optional fields
1710 Returns:
1711 A string of the intent id or None on error
1712
1713 NOTE: This function may change depending on the
1714 options developers provide for singlepoint-to-multipoint
1715 intent via cli
1716 """
1717 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001718 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001719
Jeremy Songsterff553672016-05-12 17:06:23 -07001720 if ethType:
1721 cmd += " --ethType " + str( ethType )
1722 if ethSrc:
1723 cmd += " --ethSrc " + str( ethSrc )
1724 if ethDst:
1725 cmd += " --ethDst " + str( ethDst )
1726 if bandwidth:
1727 cmd += " --bandwidth " + str( bandwidth )
1728 if lambdaAlloc:
1729 cmd += " --lambda "
1730 if ipProto:
1731 cmd += " --ipProto " + str( ipProto )
1732 if ipSrc:
1733 cmd += " --ipSrc " + str( ipSrc )
1734 if ipDst:
1735 cmd += " --ipDst " + str( ipDst )
1736 if tcpSrc:
1737 cmd += " --tcpSrc " + str( tcpSrc )
1738 if tcpDst:
1739 cmd += " --tcpDst " + str( tcpDst )
1740 if setEthSrc:
1741 cmd += " --setEthSrc " + str( setEthSrc )
1742 if setEthDst:
1743 cmd += " --setEthDst " + str( setEthDst )
1744 if vlanId:
1745 cmd += " -v " + str( vlanId )
1746 if setVlan:
1747 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001748 if partial:
1749 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001750 if encap:
1751 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001752
1753 # Check whether the user appended the port
1754 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001755
kelvin-onlabb9408212015-04-01 13:34:04 -07001756 if "/" in ingressDevice:
1757 cmd += " " + str( ingressDevice )
1758 else:
1759 if not portIngress:
1760 main.log.error( "You must specify " +
1761 "the Ingress port" )
1762 return main.FALSE
1763
1764 cmd += " " +\
1765 str( ingressDevice ) + "/" +\
1766 str( portIngress )
1767
1768 if portEgressList is None:
1769 for egressDevice in egressDeviceList:
1770 if "/" in egressDevice:
1771 cmd += " " + str( egressDevice )
1772 else:
1773 main.log.error( "You must specify " +
1774 "the egress port" )
1775 # TODO: perhaps more meaningful return
1776 return main.FALSE
1777 else:
1778 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001779 for egressDevice, portEgress in zip( egressDeviceList,
1780 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001781 cmd += " " + \
1782 str( egressDevice ) + "/" +\
1783 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001784 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001785 main.log.error( "Device list and port list does not " +
1786 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001787 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001788 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001789 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001790 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001791 # If error, return error message
1792 if re.search( "Error", handle ):
1793 main.log.error( "Error in adding singlepoint-to-multipoint " +
1794 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001795 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001796 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001797 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001798 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001799 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001800 else:
1801 main.log.error( "Error, intent ID not found" )
1802 return None
Jon Hallc6793552016-01-19 14:18:37 -08001803 except AssertionError:
1804 main.log.exception( "" )
1805 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001806 except TypeError:
1807 main.log.exception( self.name + ": Object not as expected" )
1808 return None
shahshreyad0c80432014-12-04 16:56:05 -08001809 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001810 main.log.error( self.name + ": EOF exception found" )
1811 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001812 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001813 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001814 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001815 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001816
Hari Krishna9e232602015-04-13 17:29:08 -07001817 def addMplsIntent(
1818 self,
1819 ingressDevice,
1820 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001821 ingressPort="",
1822 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001823 ethType="",
1824 ethSrc="",
1825 ethDst="",
1826 bandwidth="",
1827 lambdaAlloc=False,
1828 ipProto="",
1829 ipSrc="",
1830 ipDst="",
1831 tcpSrc="",
1832 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001833 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001834 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001835 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001836 """
1837 Required:
1838 * ingressDevice: device id of ingress device
1839 * egressDevice: device id of egress device
1840 Optional:
1841 * ethType: specify ethType
1842 * ethSrc: specify ethSrc ( i.e. src mac addr )
1843 * ethDst: specify ethDst ( i.e. dst mac addr )
1844 * bandwidth: specify bandwidth capacity of link
1845 * lambdaAlloc: if True, intent will allocate lambda
1846 for the specified intent
1847 * ipProto: specify ip protocol
1848 * ipSrc: specify ip source address
1849 * ipDst: specify ip destination address
1850 * tcpSrc: specify tcp source port
1851 * tcpDst: specify tcp destination port
1852 * ingressLabel: Ingress MPLS label
1853 * egressLabel: Egress MPLS label
1854 Description:
1855 Adds MPLS intent by
1856 specifying device id's and optional fields
1857 Returns:
1858 A string of the intent id or None on error
1859
1860 NOTE: This function may change depending on the
1861 options developers provide for MPLS
1862 intent via cli
1863 """
1864 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001865 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001866
Jeremy Songsterff553672016-05-12 17:06:23 -07001867 if ethType:
1868 cmd += " --ethType " + str( ethType )
1869 if ethSrc:
1870 cmd += " --ethSrc " + str( ethSrc )
1871 if ethDst:
1872 cmd += " --ethDst " + str( ethDst )
1873 if bandwidth:
1874 cmd += " --bandwidth " + str( bandwidth )
1875 if lambdaAlloc:
1876 cmd += " --lambda "
1877 if ipProto:
1878 cmd += " --ipProto " + str( ipProto )
1879 if ipSrc:
1880 cmd += " --ipSrc " + str( ipSrc )
1881 if ipDst:
1882 cmd += " --ipDst " + str( ipDst )
1883 if tcpSrc:
1884 cmd += " --tcpSrc " + str( tcpSrc )
1885 if tcpDst:
1886 cmd += " --tcpDst " + str( tcpDst )
1887 if ingressLabel:
1888 cmd += " --ingressLabel " + str( ingressLabel )
1889 if egressLabel:
1890 cmd += " --egressLabel " + str( egressLabel )
1891 if priority:
1892 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001893
1894 # Check whether the user appended the port
1895 # or provided it as an input
1896 if "/" in ingressDevice:
1897 cmd += " " + str( ingressDevice )
1898 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001899 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001900 main.log.error( "You must specify the ingress port" )
1901 return None
1902
1903 cmd += " " + \
1904 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001905 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001906
1907 if "/" in egressDevice:
1908 cmd += " " + str( egressDevice )
1909 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001910 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001911 main.log.error( "You must specify the egress port" )
1912 return None
1913
1914 cmd += " " +\
1915 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001916 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001917
1918 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001919 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001920 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001921 # If error, return error message
1922 if re.search( "Error", handle ):
1923 main.log.error( "Error in adding mpls intent" )
1924 return None
1925 else:
1926 # TODO: print out all the options in this message?
1927 main.log.info( "MPLS intent installed between " +
1928 str( ingressDevice ) + " and " +
1929 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001930 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07001931 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001932 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07001933 else:
1934 main.log.error( "Error, intent ID not found" )
1935 return None
Jon Hallc6793552016-01-19 14:18:37 -08001936 except AssertionError:
1937 main.log.exception( "" )
1938 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001939 except TypeError:
1940 main.log.exception( self.name + ": Object not as expected" )
1941 return None
1942 except pexpect.EOF:
1943 main.log.error( self.name + ": EOF exception found" )
1944 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001945 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001946 except Exception:
1947 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001948 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001949
Jon Hallefbd9792015-03-05 16:11:36 -08001950 def removeIntent( self, intentId, app='org.onosproject.cli',
1951 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001952 """
shahshreya1c818fc2015-02-26 13:44:08 -08001953 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001954 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001955 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001956 -p or --purge: Purge the intent from the store after removal
1957
Jon Halle3f39ff2015-01-13 11:50:53 -08001958 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001959 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001960 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001961 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001962 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001963 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001964 if purge:
1965 cmdStr += " -p"
1966 if sync:
1967 cmdStr += " -s"
1968
1969 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001970 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001971 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001972 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001973 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001974 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001975 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001976 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001977 # TODO: Should this be main.TRUE
1978 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001979 except AssertionError:
1980 main.log.exception( "" )
1981 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001982 except TypeError:
1983 main.log.exception( self.name + ": Object not as expected" )
1984 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001985 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001986 main.log.error( self.name + ": EOF exception found" )
1987 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001988 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001989 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001990 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001991 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04001992
YPZhangfebf7302016-05-24 16:45:56 -07001993 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001994 """
1995 Description:
1996 Remove all the intents
1997 Optional args:-
1998 -s or --sync: Waits for the removal before returning
1999 -p or --purge: Purge the intent from the store after removal
2000 Returns:
2001 Returns main.TRUE if all intents are removed, otherwise returns
2002 main.FALSE; Returns None for exception
2003 """
2004 try:
2005 cmdStr = "remove-intent"
2006 if purge:
2007 cmdStr += " -p"
2008 if sync:
2009 cmdStr += " -s"
2010
2011 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07002012 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08002013 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08002014 assert "Command not found:" not in handle, handle
2015 if re.search( "Error", handle ):
2016 main.log.error( "Error in removing intent" )
2017 return main.FALSE
2018 else:
2019 return main.TRUE
2020 except AssertionError:
2021 main.log.exception( "" )
2022 return None
2023 except TypeError:
2024 main.log.exception( self.name + ": Object not as expected" )
2025 return None
2026 except pexpect.EOF:
2027 main.log.error( self.name + ": EOF exception found" )
2028 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002029 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002030 except Exception:
2031 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002032 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08002033
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002034 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002035 """
2036 Purges all WITHDRAWN Intents
2037 """
2038 try:
2039 cmdStr = "purge-intents"
2040 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002041 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002042 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002043 if re.search( "Error", handle ):
2044 main.log.error( "Error in purging intents" )
2045 return main.FALSE
2046 else:
2047 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002048 except AssertionError:
2049 main.log.exception( "" )
2050 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002051 except TypeError:
2052 main.log.exception( self.name + ": Object not as expected" )
2053 return None
2054 except pexpect.EOF:
2055 main.log.error( self.name + ": EOF exception found" )
2056 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002057 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002058 except Exception:
2059 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002060 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07002061
Devin Lime6fe3c42017-10-18 16:28:40 -07002062 def wipeout( self ):
2063 """
2064 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
2065 """
2066 try:
2067 cmdStr = "wipe-out please"
2068 handle = self.sendline( cmdStr, timeout=60 )
2069 assert handle is not None, "Error in sendline"
2070 assert "Command not found:" not in handle, handle
2071 return main.TRUE
2072 except AssertionError:
2073 main.log.exception( "" )
2074 return None
2075 except TypeError:
2076 main.log.exception( self.name + ": Object not as expected" )
2077 return None
2078 except pexpect.EOF:
2079 main.log.error( self.name + ": EOF exception found" )
2080 main.log.error( self.name + ": " + self.handle.before )
2081 main.cleanAndExit()
2082 except Exception:
2083 main.log.exception( self.name + ": Uncaught exception!" )
2084 main.cleanAndExit()
2085
kelvin-onlabd3b64892015-01-20 13:26:24 -08002086 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002087 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002088 NOTE: This method should be used after installing application:
2089 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002090 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002091 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002092 Description:
2093 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002094 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002095 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002096 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002097 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002098 cmdStr += " -j"
2099 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002100 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002101 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002102 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002103 except AssertionError:
2104 main.log.exception( "" )
2105 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002106 except TypeError:
2107 main.log.exception( self.name + ": Object not as expected" )
2108 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002109 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002110 main.log.error( self.name + ": EOF exception found" )
2111 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002112 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002113 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002114 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002115 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002116
pingping-lin54b03372015-08-13 14:43:10 -07002117 def ipv4RouteNumber( self ):
2118 """
2119 NOTE: This method should be used after installing application:
2120 onos-app-sdnip
2121 Description:
2122 Obtain the total IPv4 routes number in the system
2123 """
2124 try:
Pratik Parab57963572017-05-09 11:37:54 -07002125 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002126 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002127 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002128 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002129 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002130 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002131 except AssertionError:
2132 main.log.exception( "" )
2133 return None
2134 except ( TypeError, ValueError ):
2135 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002136 return None
2137 except pexpect.EOF:
2138 main.log.error( self.name + ": EOF exception found" )
2139 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002140 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002141 except Exception:
2142 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002143 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002144
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002145 # =============Function to check Bandwidth allocation========
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002146 def allocations( self, jsonFormat = True, dollarSign = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002147 """
2148 Description:
2149 Obtain Bandwidth Allocation Information from ONOS cli.
2150 """
2151 try:
2152 cmdStr = "allocations"
2153 if jsonFormat:
2154 cmdStr += " -j"
2155 handle = self.sendline( cmdStr, timeout=300, dollarSign=True )
2156 assert handle is not None, "Error in sendline"
2157 assert "Command not found:" not in handle, handle
2158 return handle
2159 except AssertionError:
2160 main.log.exception( "" )
2161 return None
2162 except ( TypeError, ValueError ):
2163 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2164 return None
2165 except pexpect.EOF:
2166 main.log.error( self.name + ": EOF exception found" )
2167 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002168 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002169 except Exception:
2170 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002171 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002172
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002173 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002174 """
andrewonlabe6745342014-10-17 14:29:13 -04002175 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002176 Obtain intents from the ONOS cli.
2177 Optional:
2178 * jsonFormat: Enable output formatting in json, default to True
2179 * summary: Whether only output the intent summary, defaults to False
2180 * type: Only output a certain type of intent. This options is valid
2181 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002182 """
andrewonlabe6745342014-10-17 14:29:13 -04002183 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002184 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002185 if summary:
2186 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002187 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002188 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002189 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002190 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002191 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002192 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002193 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002194 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002195 else:
Jon Hallff566d52016-01-15 14:45:36 -08002196 intentType = ""
2197 # IF we want the summary of a specific intent type
2198 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002199 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002200 if intentType in jsonResult.keys():
2201 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002202 else:
Jon Hallff566d52016-01-15 14:45:36 -08002203 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002204 return handle
2205 else:
2206 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002207 except AssertionError:
2208 main.log.exception( "" )
2209 return None
2210 except ( TypeError, ValueError ):
2211 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002212 return None
2213 except pexpect.EOF:
2214 main.log.error( self.name + ": EOF exception found" )
2215 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002216 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002217 except Exception:
2218 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002219 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002220
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002221 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002222 """
You Wangfdcbfc42016-05-16 12:16:53 -07002223 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002224 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002225 list of intent IDs.
2226 Parameters:
2227 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002228 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002229 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002230 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002231 accepted.
2232 Returns a list of dictionaries if a list of intent IDs is accepted,
2233 and each dictionary maps 'id' to the Intent ID and 'state' to
2234 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002235 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002236
kelvin-onlab54400a92015-02-26 18:05:51 -08002237 try:
2238 state = "State is Undefined"
2239 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002240 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002241 else:
Jon Hallc6793552016-01-19 14:18:37 -08002242 rawJson = intentsJson
2243 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002244 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002245 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002246 if intentsId == intent[ 'id' ]:
2247 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002248 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002249 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002250 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002251 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002252 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002253 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002254 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002255 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002256 for intent in parsedIntentsJson:
2257 if intentsId[ i ] == intent[ 'id' ]:
2258 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002259 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002260 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002261 break
Jon Hallefbd9792015-03-05 16:11:36 -08002262 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002263 main.log.warn( "Could not find all intents in ONOS output" )
2264 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002265 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002266 else:
Jon Hall53158082017-05-18 11:17:00 -07002267 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002268 return None
Jon Hallc6793552016-01-19 14:18:37 -08002269 except ( TypeError, ValueError ):
2270 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002271 return None
2272 except pexpect.EOF:
2273 main.log.error( self.name + ": EOF exception found" )
2274 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002275 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002276 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002277 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002278 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002279
Jon Hallf539eb92017-05-22 17:18:42 -07002280 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002281 """
2282 Description:
2283 Check intents state
2284 Required:
2285 intentsId - List of intents ID to be checked
2286 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002287 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002288 state in the list.
2289 *NOTE: You can pass in a list of expected state,
2290 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002291 Return:
Jon Hall53158082017-05-18 11:17:00 -07002292 Returns main.TRUE only if all intent are the same as expected states,
2293 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002294 """
2295 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002296 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002297 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002298
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002299 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002300 intentsDict = []
2301 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002302 if isinstance( intentsId, types.StringType ) \
2303 and intent.get( 'id' ) == intentsId:
2304 intentsDict.append( intent )
2305 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002306 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002307 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002308
2309 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002310 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002311 "getting intents state" )
2312 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002313
2314 if isinstance( expectedState, types.StringType ):
2315 for intents in intentsDict:
2316 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002317 main.log.debug( self.name + " : Intent ID - " +
2318 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002319 " actual state = " +
2320 intents.get( 'state' )
2321 + " does not equal expected state = "
2322 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002323 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002324 elif isinstance( expectedState, types.ListType ):
2325 for intents in intentsDict:
2326 if not any( state == intents.get( 'state' ) for state in
2327 expectedState ):
2328 main.log.debug( self.name + " : Intent ID - " +
2329 intents.get( 'id' ) +
2330 " actual state = " +
2331 intents.get( 'state' ) +
2332 " does not equal expected states = "
2333 + str( expectedState ) )
2334 returnValue = main.FALSE
2335
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002336 if returnValue == main.TRUE:
2337 main.log.info( self.name + ": All " +
2338 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002339 " intents are in " + str( expectedState ) +
2340 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002341 return returnValue
2342 except TypeError:
2343 main.log.exception( self.name + ": Object not as expected" )
2344 return None
2345 except pexpect.EOF:
2346 main.log.error( self.name + ": EOF exception found" )
2347 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002348 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002349 except Exception:
2350 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002351 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002352
Jon Hallf539eb92017-05-22 17:18:42 -07002353 def compareBandwidthAllocations( self, expectedAllocations ):
2354 """
2355 Description:
2356 Compare the allocated bandwidth with the given allocations
2357 Required:
2358 expectedAllocations - The expected ONOS output of the allocations command
2359 Return:
2360 Returns main.TRUE only if all intent are the same as expected states,
2361 otherwise returns main.FALSE.
2362 """
2363 # FIXME: Convert these string comparisons to object comparisons
2364 try:
2365 returnValue = main.TRUE
2366 bandwidthFailed = False
2367 rawAlloc = self.allocations()
2368 expectedFormat = StringIO( expectedAllocations )
2369 ONOSOutput = StringIO( rawAlloc )
2370 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2371 str( expectedFormat ) ) )
2372
2373 for actual, expected in izip( ONOSOutput, expectedFormat ):
2374 actual = actual.rstrip()
2375 expected = expected.rstrip()
2376 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2377 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002378 marker1 = actual.find( 'allocated' )
2379 m1 = actual[ :marker1 ]
2380 marker2 = expected.find( 'allocated' )
2381 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002382 if m1 != m2:
2383 bandwidthFailed = True
2384 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2385 bandwidthFailed = True
2386 expectedFormat.close()
2387 ONOSOutput.close()
2388
2389 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002390 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002391 returnValue = main.FALSE
2392 return returnValue
2393 except TypeError:
2394 main.log.exception( self.name + ": Object not as expected" )
2395 return None
2396 except pexpect.EOF:
2397 main.log.error( self.name + ": EOF exception found" )
2398 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002399 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002400 except Exception:
2401 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002402 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002403
You Wang66518af2016-05-16 15:32:59 -07002404 def compareIntent( self, intentDict ):
2405 """
2406 Description:
2407 Compare the intent ids and states provided in the argument with all intents in ONOS
2408 Return:
2409 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2410 Arguments:
2411 intentDict: a dictionary which maps intent ids to intent states
2412 """
2413 try:
2414 intentsRaw = self.intents()
2415 intentsJson = json.loads( intentsRaw )
2416 intentDictONOS = {}
2417 for intent in intentsJson:
2418 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002419 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002420 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002421 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002422 str( len( intentDict ) ) + " expected and " +
2423 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002424 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002425 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002426 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002427 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2428 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002429 else:
2430 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2431 main.log.debug( self.name + ": intent ID - " + intentID +
2432 " expected state is " + intentDict[ intentID ] +
2433 " but actual state is " + intentDictONOS[ intentID ] )
2434 returnValue = main.FALSE
2435 intentDictONOS.pop( intentID )
2436 if len( intentDictONOS ) > 0:
2437 returnValue = main.FALSE
2438 for intentID in intentDictONOS.keys():
2439 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002440 if returnValue == main.TRUE:
2441 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2442 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002443 except KeyError:
2444 main.log.exception( self.name + ": KeyError exception found" )
2445 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002446 except ( TypeError, ValueError ):
2447 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002448 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002449 except pexpect.EOF:
2450 main.log.error( self.name + ": EOF exception found" )
2451 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002452 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002453 except Exception:
2454 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002455 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002456
YPZhang14a4aa92016-07-15 13:37:15 -07002457 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002458 """
2459 Description:
2460 Check the number of installed intents.
2461 Optional:
2462 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002463 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002464 Return:
2465 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2466 , otherwise, returns main.FALSE.
2467 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002468
GlennRCed771242016-01-13 17:02:47 -08002469 try:
2470 cmd = "intents -s -j"
2471
2472 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002473 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002474 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002475 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002476 response = json.loads( response )
2477
2478 # get total and installed number, see if they are match
2479 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002480 if allState.get( 'total' ) == allState.get( 'installed' ):
Jon Halla478b852017-12-04 15:00:15 -08002481 main.log.info( 'Total Intents: {} Installed Intents: {}'.format(
2482 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002483 return main.TRUE
Jon Halla478b852017-12-04 15:00:15 -08002484 main.log.info( 'Verified Intents failed Expected intents: {} installed intents: {}'.format(
2485 allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002486 return main.FALSE
2487
Jon Hallc6793552016-01-19 14:18:37 -08002488 except ( TypeError, ValueError ):
2489 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002490 return None
2491 except pexpect.EOF:
2492 main.log.error( self.name + ": EOF exception found" )
2493 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002494 if noExit:
2495 return main.FALSE
2496 else:
Devin Lim44075962017-08-11 10:56:37 -07002497 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002498 except pexpect.TIMEOUT:
2499 main.log.error( self.name + ": ONOS timeout" )
2500 return None
GlennRCed771242016-01-13 17:02:47 -08002501 except Exception:
2502 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002503 if noExit:
2504 return main.FALSE
2505 else:
Devin Lim44075962017-08-11 10:56:37 -07002506 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002507
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002508 def flows( self, state="any", jsonFormat=True, timeout=60, noExit=False, noCore=False, device=""):
kelvin8ec71442015-01-15 16:57:00 -08002509 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002510 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002511 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002512 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002513 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002514 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002515 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002516 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002517 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002518 if jsonFormat:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002519 cmdStr += " -j"
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002520 if noCore:
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002521 cmdStr += " -n"
2522 cmdStr += " " + state
2523 cmdStr += " " + device
YPZhangebf9eb52016-05-12 15:20:24 -07002524 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002525 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002526 assert "Command not found:" not in handle, handle
2527 if re.search( "Error:", handle ):
2528 main.log.error( self.name + ": flows() response: " +
2529 str( handle ) )
2530 return handle
2531 except AssertionError:
2532 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002533 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002534 except TypeError:
2535 main.log.exception( self.name + ": Object not as expected" )
2536 return None
Jon Hallc6793552016-01-19 14:18:37 -08002537 except pexpect.TIMEOUT:
2538 main.log.error( self.name + ": ONOS timeout" )
2539 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002540 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002541 main.log.error( self.name + ": EOF exception found" )
2542 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002543 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002544 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002545 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002546 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002547
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002548 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002549 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002550 count = int( count ) if count else 0
2551 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002552
Jon Halle0f0b342017-04-18 11:43:47 -07002553 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002554 """
2555 Description:
GlennRCed771242016-01-13 17:02:47 -08002556 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002557 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2558 if the count of those states is 0, which means all current flows
2559 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002560 Optional:
GlennRCed771242016-01-13 17:02:47 -08002561 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002562 Return:
2563 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002564 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002565 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002566 """
2567 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002568 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002569 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002570 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002571 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002572 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002573 if rawFlows:
2574 # if we didn't get flows or flows function return None, we should return
2575 # main.Flase
2576 checkedStates.append( json.loads( rawFlows ) )
2577 else:
2578 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002579 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002580 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002581 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002582 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002583 except TypeError:
2584 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002585 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002586
GlennRCed771242016-01-13 17:02:47 -08002587 # We want to count PENDING_ADD if isPENDING is true
2588 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002589 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002590 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002591 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002592 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002593 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002594 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002595 except ( TypeError, ValueError ):
2596 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002597 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002598
YPZhang240842b2016-05-17 12:00:50 -07002599 except AssertionError:
2600 main.log.exception( "" )
2601 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002602 except pexpect.TIMEOUT:
2603 main.log.error( self.name + ": ONOS timeout" )
2604 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002605 except pexpect.EOF:
2606 main.log.error( self.name + ": EOF exception found" )
2607 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002608 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002609 except Exception:
2610 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002611 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002612
GlennRCed771242016-01-13 17:02:47 -08002613 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002614 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002615 """
andrewonlab87852b02014-11-19 18:44:19 -05002616 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002617 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002618 a specific point-to-point intent definition
2619 Required:
GlennRCed771242016-01-13 17:02:47 -08002620 * ingress: specify source dpid
2621 * egress: specify destination dpid
2622 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002623 Optional:
GlennRCed771242016-01-13 17:02:47 -08002624 * offset: the keyOffset is where the next batch of intents
2625 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002626 * noExit: If set to True, TestON will not exit if any error when issus command
2627 * getResponse: If set to True, function will return ONOS response.
2628
GlennRCed771242016-01-13 17:02:47 -08002629 Returns: If failed to push test intents, it will returen None,
2630 if successful, return true.
2631 Timeout expection will return None,
2632 TypeError will return false
2633 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002634 """
andrewonlab87852b02014-11-19 18:44:19 -05002635 try:
GlennRCed771242016-01-13 17:02:47 -08002636 if background:
2637 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002638 else:
GlennRCed771242016-01-13 17:02:47 -08002639 back = ""
2640 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002641 ingress,
2642 egress,
2643 batchSize,
2644 offset,
2645 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002646 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002647 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002648 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002649 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002650 if getResponse:
2651 return response
2652
GlennRCed771242016-01-13 17:02:47 -08002653 # TODO: We should handle if there is failure in installation
2654 return main.TRUE
2655
Jon Hallc6793552016-01-19 14:18:37 -08002656 except AssertionError:
2657 main.log.exception( "" )
2658 return None
GlennRCed771242016-01-13 17:02:47 -08002659 except pexpect.TIMEOUT:
2660 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002661 return None
andrewonlab87852b02014-11-19 18:44:19 -05002662 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002663 main.log.error( self.name + ": EOF exception found" )
2664 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002665 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002666 except TypeError:
2667 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002668 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002669 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002670 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002671 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002672
YPZhangebf9eb52016-05-12 15:20:24 -07002673 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002674 """
2675 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002676 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002677 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002678 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002679 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002680 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002681
YPZhangb5d3f832016-01-23 22:54:26 -08002682 try:
YPZhange3109a72016-02-02 11:25:37 -08002683 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002684 cmd = "flows -c added"
2685 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2686 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002687 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002688 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002689 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002690 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002691 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002692 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002693 return None
2694 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002695
You Wangd3cb2ce2016-05-16 14:01:24 -07002696 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002697 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002698 return None
2699 except pexpect.EOF:
2700 main.log.error( self.name + ": EOF exception found" )
2701 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002702 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002703 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002704 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002705 except pexpect.TIMEOUT:
2706 main.log.error( self.name + ": ONOS timeout" )
2707 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002708 except Exception:
2709 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002710 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002711 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002712 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002713
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002714 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002715 """
2716 Description:
2717 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002718 Optional:
2719 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002720 Return:
2721 The number of intents
2722 """
2723 try:
2724 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002725 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002726 if response is None:
2727 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002728 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002729 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002730 except ( TypeError, ValueError ):
2731 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002732 return None
2733 except pexpect.EOF:
2734 main.log.error( self.name + ": EOF exception found" )
2735 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002736 if noExit:
2737 return -1
2738 else:
Devin Lim44075962017-08-11 10:56:37 -07002739 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002740 except Exception:
2741 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002742 if noExit:
2743 return -1
2744 else:
Devin Lim44075962017-08-11 10:56:37 -07002745 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002746
kelvin-onlabd3b64892015-01-20 13:26:24 -08002747 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002748 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002749 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002750 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002751 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002752 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002753 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002754 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002755 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002756 cmdStr += " -j"
2757 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002758 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002759 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002760 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002761 except AssertionError:
2762 main.log.exception( "" )
2763 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002764 except TypeError:
2765 main.log.exception( self.name + ": Object not as expected" )
2766 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002767 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002768 main.log.error( self.name + ": EOF exception found" )
2769 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002770 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002771 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002772 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002773 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002774
kelvin-onlabd3b64892015-01-20 13:26:24 -08002775 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002776 """
2777 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002778 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002779 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002780 """
andrewonlab867212a2014-10-22 20:13:38 -04002781 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002782 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002783 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002784 cmdStr += " -j"
2785 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002786 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002787 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002788 if handle:
2789 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002790 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002791 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002792 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002793 else:
2794 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002795 except AssertionError:
2796 main.log.exception( "" )
2797 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002798 except TypeError:
2799 main.log.exception( self.name + ": Object not as expected" )
2800 return None
andrewonlab867212a2014-10-22 20:13:38 -04002801 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002802 main.log.error( self.name + ": EOF exception found" )
2803 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002804 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002805 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002806 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002807 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002808
kelvin8ec71442015-01-15 16:57:00 -08002809 # Wrapper functions ****************
2810 # Wrapper functions use existing driver
2811 # functions and extends their use case.
2812 # For example, we may use the output of
2813 # a normal driver function, and parse it
2814 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002815
kelvin-onlabd3b64892015-01-20 13:26:24 -08002816 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002817 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002818 Description:
2819 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002820 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002821 try:
kelvin8ec71442015-01-15 16:57:00 -08002822 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002823 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002824 if intentsStr is None:
2825 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002826 # Convert to a dictionary
2827 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002828 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002829 for intent in intents:
2830 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002831 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002832 except TypeError:
2833 main.log.exception( self.name + ": Object not as expected" )
2834 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002835 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002836 main.log.error( self.name + ": EOF exception found" )
2837 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002838 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002839 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002840 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002841 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002842
You Wang3c276252016-09-21 15:21:36 -07002843 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002844 """
2845 Determine the number of flow rules for the given device id that are
2846 in the added state
You Wang3c276252016-09-21 15:21:36 -07002847 Params:
2848 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002849 """
2850 try:
You Wang3c276252016-09-21 15:21:36 -07002851 if core:
2852 cmdStr = "flows any " + str( deviceId ) + " | " +\
2853 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2854 else:
2855 cmdStr = "flows any " + str( deviceId ) + " | " +\
2856 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002857 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002858 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002859 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002860 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002861 except AssertionError:
2862 main.log.exception( "" )
2863 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002864 except pexpect.EOF:
2865 main.log.error( self.name + ": EOF exception found" )
2866 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002867 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002868 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002869 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002870 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002871
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002872 def groupAddedCount( self, deviceId, core=False ):
2873 """
2874 Determine the number of group rules for the given device id that are
2875 in the added state
2876 Params:
2877 core: if True, only return the number of core groups added
2878 """
2879 try:
2880 if core:
2881 cmdStr = "groups any " + str( deviceId ) + " | " +\
2882 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2883 else:
2884 cmdStr = "groups any " + str( deviceId ) + " | " +\
2885 "grep 'state=ADDED' | wc -l"
2886 handle = self.sendline( cmdStr )
2887 assert handle is not None, "Error in sendline"
2888 assert "Command not found:" not in handle, handle
2889 return handle
2890 except AssertionError:
2891 main.log.exception( "" )
2892 return None
2893 except pexpect.EOF:
2894 main.log.error( self.name + ": EOF exception found" )
2895 main.log.error( self.name + ": " + self.handle.before )
2896 main.cleanAndExit()
2897 except Exception:
2898 main.log.exception( self.name + ": Uncaught exception!" )
2899 main.cleanAndExit()
2900
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002901 def addStaticRoute( self, subnet, intf):
2902 """
2903 Adds a static route to onos.
2904 Params:
2905 subnet: The subnet reaching through this route
2906 intf: The interface this route is reachable through
2907 """
2908 try:
2909 cmdStr = "route-add " + subnet + " " + intf
2910 handle = self.sendline( cmdStr )
2911 assert handle is not None, "Error in sendline"
2912 assert "Command not found:" not in handle, handle
2913 return handle
2914 except AssertionError:
2915 main.log.exception( "" )
2916 return None
2917 except pexpect.EOF:
2918 main.log.error( self.name + ": EOF exception found" )
2919 main.log.error( self.name + ": " + self.handle.before )
2920 main.cleanAndExit()
2921 except Exception:
2922 main.log.exception( self.name + ": Uncaught exception!" )
2923 main.cleanAndExit()
2924
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002925 def checkGroupAddedCount( self, deviceId, expectedGroupCount=0, core=False, comparison=0):
2926 """
2927 Description:
2928 Check whether the number of groups for the given device id that
2929 are in ADDED state is bigger than minGroupCount.
2930 Required:
2931 * deviceId: device id to check the number of added group rules
2932 Optional:
2933 * minGroupCount: the number of groups to compare
2934 * core: if True, only check the number of core groups added
2935 * comparison: if 0, compare with greater than minFlowCount
2936 * if 1, compare with equal to minFlowCount
2937 Return:
2938 Returns the number of groups if it is bigger than minGroupCount,
2939 returns main.FALSE otherwise.
2940 """
2941 count = self.groupAddedCount( deviceId, core )
2942 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07002943 main.log.debug( "found {} groups".format( count ) )
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002944 return count if ((count > expectedGroupCount) if (comparison == 0) else (count == expectedGroupCount)) else main.FALSE
2945
You Wangc02f3be2018-05-18 12:14:23 -07002946 def getGroups( self, deviceId, groupType="any" ):
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002947 """
2948 Retrieve groups from a specific device.
You Wangc02f3be2018-05-18 12:14:23 -07002949 deviceId: Id of the device from which we retrieve groups
2950 groupType: Type of group
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002951 """
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002952 try:
You Wangc02f3be2018-05-18 12:14:23 -07002953 groupCmd = "groups -t {0} any {1}".format( groupType, deviceId )
2954 handle = self.sendline( groupCmd )
Andreas Pantelopoulosdf5061f2018-05-15 11:46:59 -07002955 assert handle is not None, "Error in sendline"
2956 assert "Command not found:" not in handle, handle
2957 return handle
2958 except AssertionError:
2959 main.log.exception( "" )
2960 return None
2961 except TypeError:
2962 main.log.exception( self.name + ": Object not as expected" )
2963 return None
2964 except pexpect.EOF:
2965 main.log.error( self.name + ": EOF exception found" )
2966 main.log.error( self.name + ": " + self.handle.before )
2967 main.cleanAndExit()
2968 except Exception:
2969 main.log.exception( self.name + ": Uncaught exception!" )
2970 main.cleanAndExit()
2971
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002972 def checkFlowAddedCount( self, deviceId, expectedFlowCount=0, core=False, comparison=0):
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002973 """
2974 Description:
2975 Check whether the number of flow rules for the given device id that
2976 are in ADDED state is bigger than minFlowCount.
2977 Required:
2978 * deviceId: device id to check the number of added flow rules
2979 Optional:
2980 * minFlowCount: the number of flow rules to compare
2981 * core: if True, only check the number of core flows added
Andreas Pantelopoulos9173d442018-03-01 17:07:37 -08002982 * comparison: if 0, compare with greater than minFlowCount
2983 * if 1, compare with equal to minFlowCount
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002984 Return:
2985 Returns the number of flow rules if it is bigger than minFlowCount,
2986 returns main.FALSE otherwise.
2987 """
2988 count = self.flowAddedCount( deviceId, core )
2989 count = int( count ) if count else 0
Jon Hall9677ed32018-04-24 11:16:23 -07002990 main.log.debug( "found {} flows".format( count ) )
Andreas Pantelopoulos2eae3242018-03-06 13:47:20 -08002991 return count if ((count > expectedFlowCount) if (comparison == 0) else (count == expectedFlowCount)) else main.FALSE
Jonghwan Hyuncf2345c2018-02-26 11:07:54 -08002992
kelvin-onlabd3b64892015-01-20 13:26:24 -08002993 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002994 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002995 Use 'devices' function to obtain list of all devices
2996 and parse the result to obtain a list of all device
2997 id's. Returns this list. Returns empty list if no
2998 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002999 List is ordered sequentially
3000
andrewonlab3e15ead2014-10-15 14:21:34 -04003001 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08003002 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04003003 the ids. By obtaining the list of device ids on the fly,
3004 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08003005 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04003006 try:
kelvin8ec71442015-01-15 16:57:00 -08003007 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08003008 devicesStr = self.devices( jsonFormat=False )
3009 idList = []
kelvin8ec71442015-01-15 16:57:00 -08003010
kelvin-onlabd3b64892015-01-20 13:26:24 -08003011 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08003012 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003013 return idList
kelvin8ec71442015-01-15 16:57:00 -08003014
3015 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08003016 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08003017 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08003018 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08003019 # Split list further into arguments before and after string
3020 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08003021 # append to idList
3022 for arg in tempList:
3023 idList.append( arg.split( "id=" )[ 1 ] )
3024 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04003025
Jon Halld4d4b372015-01-28 16:02:41 -08003026 except TypeError:
3027 main.log.exception( self.name + ": Object not as expected" )
3028 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04003029 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003030 main.log.error( self.name + ": EOF exception found" )
3031 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003032 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003033 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003034 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003035 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003036
kelvin-onlabd3b64892015-01-20 13:26:24 -08003037 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08003038 """
andrewonlab7c211572014-10-15 16:45:20 -04003039 Uses 'nodes' function to obtain list of all nodes
3040 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08003041 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04003042 Returns:
3043 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08003044 """
andrewonlab7c211572014-10-15 16:45:20 -04003045 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07003046 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003047 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003048 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07003049 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08003050 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08003051 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003052 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07003053 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003054 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08003055 return idList
Jon Hallc6793552016-01-19 14:18:37 -08003056 except ( TypeError, ValueError ):
3057 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003058 return None
andrewonlab7c211572014-10-15 16:45:20 -04003059 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003060 main.log.error( self.name + ": EOF exception found" )
3061 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003062 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003063 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003064 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003065 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04003066
kelvin-onlabd3b64892015-01-20 13:26:24 -08003067 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08003068 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003069 Return the first device from the devices api whose 'id' contains 'dpid'
3070 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08003071 """
Jon Halla91c4dc2014-10-22 12:57:04 -04003072 try:
kelvin8ec71442015-01-15 16:57:00 -08003073 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04003074 return None
3075 else:
kelvin8ec71442015-01-15 16:57:00 -08003076 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003077 rawDevices = self.devices()
3078 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08003079 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08003080 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08003081 # print "%s in %s?" % ( dpid, device[ 'id' ] )
3082 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04003083 return device
3084 return None
Jon Hallc6793552016-01-19 14:18:37 -08003085 except ( TypeError, ValueError ):
3086 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08003087 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04003088 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003089 main.log.error( self.name + ": EOF exception found" )
3090 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003091 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003092 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003093 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003094 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04003095
You Wang24139872016-05-03 11:48:47 -07003096 def getTopology( self, topologyOutput ):
3097 """
3098 Definition:
3099 Loads a json topology output
3100 Return:
3101 topology = current ONOS topology
3102 """
3103 import json
3104 try:
3105 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003106 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07003107 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07003108 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07003109 except ( TypeError, ValueError ):
3110 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
3111 return None
You Wang24139872016-05-03 11:48:47 -07003112 except pexpect.EOF:
3113 main.log.error( self.name + ": EOF exception found" )
3114 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003115 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003116 except Exception:
3117 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003118 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07003119
Pier6a0c4de2018-03-18 16:01:30 -07003120 def checkStatus( self, numoswitch, numolink = -1, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08003121 """
Jon Hallefbd9792015-03-05 16:11:36 -08003122 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08003123 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07003124 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08003125
Flavio Castro82ee2f62016-06-07 15:04:12 -07003126 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08003127 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07003128 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07003129 logLevel = level to log to.
3130 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04003131
Jon Hallefbd9792015-03-05 16:11:36 -08003132 Returns: main.TRUE if the number of switches and links are correct,
3133 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04003134 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08003135 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003136 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003137 try:
You Wang13310252016-07-31 10:56:14 -07003138 summary = self.summary()
3139 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003140 except ( TypeError, ValueError ):
3141 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3142 return main.ERROR
3143 try:
3144 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003145 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003146 return main.ERROR
3147 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003148 # Is the number of switches is what we expected
3149 devices = topology.get( 'devices', False )
3150 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003151 nodes = summary.get( 'nodes', False )
3152 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003153 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003154 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003155 # Is the number of links is what we expected
Pier6a0c4de2018-03-18 16:01:30 -07003156 linkCheck = ( int( links ) == int( numolink ) ) or int( numolink ) == -1
Flavio Castro82ee2f62016-06-07 15:04:12 -07003157 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3158 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003159 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003160 output = output + "The number of links and switches match "\
3161 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003162 result = main.TRUE
3163 else:
You Wang24139872016-05-03 11:48:47 -07003164 output = output + \
3165 "The number of links and switches does not match " + \
3166 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003167 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003168 output = output + "\n ONOS sees %i devices" % int( devices )
3169 output = output + " (%i expected) " % int( numoswitch )
Pier6a0c4de2018-03-18 16:01:30 -07003170 if int( numolink ) > 0:
3171 output = output + "and %i links " % int( links )
3172 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003173 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003174 output = output + "and %i controllers " % int( nodes )
3175 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003176 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003177 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003178 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003179 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003180 else:
You Wang24139872016-05-03 11:48:47 -07003181 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003182 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003183 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003184 main.log.error( self.name + ": EOF exception found" )
3185 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003186 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003187 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003188 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003189 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003190
kelvin-onlabd3b64892015-01-20 13:26:24 -08003191 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003192 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003193 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003194 deviceId must be the id of a device as seen in the onos devices command
3195 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003196 role must be either master, standby, or none
3197
Jon Halle3f39ff2015-01-13 11:50:53 -08003198 Returns:
3199 main.TRUE or main.FALSE based on argument verification and
3200 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003201 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003202 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003203 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003204 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003205 cmdStr = "device-role " +\
3206 str( deviceId ) + " " +\
3207 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003208 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003209 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003210 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003211 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003212 if re.search( "Error", handle ):
3213 # end color output to escape any colours
3214 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003215 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003216 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003217 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003218 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003219 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003220 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003221 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003222 return main.FALSE
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 Hall1c9e8732014-10-27 19:29:27 -04003229 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 Hall1c9e8732014-10-27 19:29:27 -04003236
kelvin-onlabd3b64892015-01-20 13:26:24 -08003237 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003238 """
Jon Hall0dd09952018-04-19 09:59:11 -07003239 Lists all topology clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003240 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003241 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003242 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003243 try:
Jon Hall0dd09952018-04-19 09:59:11 -07003244 cmdStr = "topo-clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003245 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003246 cmdStr += " -j"
3247 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003248 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003249 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003250 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003251 except AssertionError:
3252 main.log.exception( "" )
3253 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003254 except TypeError:
3255 main.log.exception( self.name + ": Object not as expected" )
3256 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003257 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003258 main.log.error( self.name + ": EOF exception found" )
3259 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003260 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003261 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003262 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003263 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003264
kelvin-onlabd3b64892015-01-20 13:26:24 -08003265 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003266 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003267 CLI command to get the current leader for the Election test application
3268 NOTE: Requires installation of the onos-app-election feature
3269 Returns: Node IP of the leader if one exists
3270 None if none exists
3271 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003272 """
Jon Hall94fd0472014-12-08 11:52:42 -08003273 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003274 cmdStr = "election-test-leader"
3275 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003276 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003277 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003278 # Leader
3279 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003280 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003281 nodeSearch = re.search( leaderPattern, response )
3282 if nodeSearch:
3283 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003284 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003285 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003286 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003287 # no leader
3288 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003289 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003290 nullSearch = re.search( nullPattern, response )
3291 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003292 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003293 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003294 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003295 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003296 main.log.error( "Error in electionTestLeader on " + self.name +
3297 ": " + "unexpected response" )
3298 main.log.error( repr( response ) )
3299 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003300 except AssertionError:
3301 main.log.exception( "" )
3302 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003303 except TypeError:
3304 main.log.exception( self.name + ": Object not as expected" )
3305 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003306 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003307 main.log.error( self.name + ": EOF exception found" )
3308 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003309 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003310 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003311 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003312 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003313
kelvin-onlabd3b64892015-01-20 13:26:24 -08003314 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003315 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003316 CLI command to run for leadership of the Election test application.
3317 NOTE: Requires installation of the onos-app-election feature
3318 Returns: Main.TRUE on success
3319 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003320 """
Jon Hall94fd0472014-12-08 11:52:42 -08003321 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003322 cmdStr = "election-test-run"
3323 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003324 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003325 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003326 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003327 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003328 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003329 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003330 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003331 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003332 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003333 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003334 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003335 main.log.error( "Error in electionTestRun on " + self.name +
3336 ": " + "unexpected response" )
3337 main.log.error( repr( response ) )
3338 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003339 except AssertionError:
3340 main.log.exception( "" )
3341 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003342 except TypeError:
3343 main.log.exception( self.name + ": Object not as expected" )
3344 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003345 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003346 main.log.error( self.name + ": EOF exception found" )
3347 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003348 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003349 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003350 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003351 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003352
kelvin-onlabd3b64892015-01-20 13:26:24 -08003353 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003354 """
Jon Hall94fd0472014-12-08 11:52:42 -08003355 * CLI command to withdraw the local node from leadership election for
3356 * the Election test application.
3357 #NOTE: Requires installation of the onos-app-election feature
3358 Returns: Main.TRUE on success
3359 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003360 """
Jon Hall94fd0472014-12-08 11:52:42 -08003361 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003362 cmdStr = "election-test-withdraw"
3363 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003364 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003365 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003366 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003367 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003368 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003369 if re.search( successPattern, response ):
3370 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003371 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003372 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003373 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003374 main.log.error( "Error in electionTestWithdraw on " +
3375 self.name + ": " + "unexpected response" )
3376 main.log.error( repr( response ) )
3377 return main.FALSE
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 main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -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()
Jon Hall1c9e8732014-10-27 19:29:27 -04003391
kelvin8ec71442015-01-15 16:57:00 -08003392 def getDevicePortsEnabledCount( 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:
Jon Halle3f39ff2015-01-13 11:50:53 -08003397 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003398 cmdStr = "onos:ports -e " + dpid + " | 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 ):
3403 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 getDeviceLinksActiveCount( self, dpid ):
3421 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003422 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003423 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003424 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003425 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003426 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3427 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003428 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003429 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003430 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003431 main.log.error( "Error in getting ports " )
3432 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003433 return output
Jon Hallc6793552016-01-19 14:18:37 -08003434 except AssertionError:
3435 main.log.exception( "" )
3436 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003437 except TypeError:
3438 main.log.exception( self.name + ": Object not as expected" )
3439 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003440 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003441 main.log.error( self.name + ": EOF exception found" )
3442 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003443 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003444 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003445 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003446 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003447
kelvin8ec71442015-01-15 16:57:00 -08003448 def getAllIntentIds( self ):
3449 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003450 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003451 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003452 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003453 cmdStr = "onos:intents | grep id="
3454 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003455 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003456 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003457 if re.search( "Error", output ):
3458 main.log.error( "Error in getting ports" )
3459 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003460 return output
Jon Hallc6793552016-01-19 14:18:37 -08003461 except AssertionError:
3462 main.log.exception( "" )
3463 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003464 except TypeError:
3465 main.log.exception( self.name + ": Object not as expected" )
3466 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003467 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003468 main.log.error( self.name + ": EOF exception found" )
3469 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003470 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003471 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003472 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003473 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003474
Jon Hall73509952015-02-24 16:42:56 -08003475 def intentSummary( self ):
3476 """
Jon Hallefbd9792015-03-05 16:11:36 -08003477 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003478 """
3479 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003480 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003481 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003482 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003483 states.append( intent.get( 'state', None ) )
3484 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003485 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003486 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003487 except ( TypeError, ValueError ):
3488 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003489 return None
3490 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 Hallfebb1c72015-03-05 13:30:09 -08003494 except Exception:
Jon Hall73509952015-02-24 16:42:56 -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
Jon Hall61282e32015-03-19 11:34:11 -07003498 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003499 """
3500 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003501 Optional argument:
3502 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003503 """
Jon Hall63604932015-02-26 17:09:50 -08003504 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003505 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003506 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003507 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
Jon Hallc6358dd2015-04-10 12:44:28 -07003511 return output
Jon Hallc6793552016-01-19 14:18:37 -08003512 except AssertionError:
3513 main.log.exception( "" )
3514 return None
Jon Hall63604932015-02-26 17:09:50 -08003515 except TypeError:
3516 main.log.exception( self.name + ": Object not as expected" )
3517 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003518 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()
Jon Hall77ba41c2015-04-06 10:25:40 -07003522 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003523 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003524 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003525
acsmarsa4a4d1e2015-07-10 16:01:24 -07003526 def leaderCandidates( self, jsonFormat=True ):
3527 """
3528 Returns the output of the leaders -c command.
3529 Optional argument:
3530 * jsonFormat - boolean indicating if you want output in json
3531 """
3532 try:
3533 cmdStr = "onos:leaders -c"
3534 if jsonFormat:
3535 cmdStr += " -j"
3536 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003537 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003538 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003539 return output
Jon Hallc6793552016-01-19 14:18:37 -08003540 except AssertionError:
3541 main.log.exception( "" )
3542 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003543 except TypeError:
3544 main.log.exception( self.name + ": Object not as expected" )
3545 return None
3546 except pexpect.EOF:
3547 main.log.error( self.name + ": EOF exception found" )
3548 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003549 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003550 except Exception:
3551 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003552 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003553
Jon Hallc6793552016-01-19 14:18:37 -08003554 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003555 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003556 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003557 topic parameter and an empty list if the topic doesn't exist
3558 If no leader is elected leader in the returned list will be "none"
3559 Returns None if there is a type error processing the json object
3560 """
3561 try:
Jon Hall6e709752016-02-01 13:38:46 -08003562 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003563 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003564 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003565 assert "Command not found:" not in rawOutput, rawOutput
3566 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003567 results = []
3568 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003569 if dict[ "topic" ] == topic:
3570 leader = dict[ "leader" ]
3571 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003572 results.append( leader )
3573 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003574 return results
Jon Hallc6793552016-01-19 14:18:37 -08003575 except AssertionError:
3576 main.log.exception( "" )
3577 return None
3578 except ( TypeError, ValueError ):
3579 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003580 return None
3581 except pexpect.EOF:
3582 main.log.error( self.name + ": EOF exception found" )
3583 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003584 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003585 except Exception:
3586 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003587 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003588
Jon Hall61282e32015-03-19 11:34:11 -07003589 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003590 """
3591 Returns the output of the intent Pending map.
3592 """
Jon Hall63604932015-02-26 17:09:50 -08003593 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003594 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003595 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003596 cmdStr += " -j"
3597 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003598 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003599 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003600 return output
Jon Hallc6793552016-01-19 14:18:37 -08003601 except AssertionError:
3602 main.log.exception( "" )
3603 return None
Jon Hall63604932015-02-26 17:09:50 -08003604 except TypeError:
3605 main.log.exception( self.name + ": Object not as expected" )
3606 return None
3607 except pexpect.EOF:
3608 main.log.error( self.name + ": EOF exception found" )
3609 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003610 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003611 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003612 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003613 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003614
Jon Hall2c8959e2016-12-16 12:17:34 -08003615 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003616 """
3617 Returns the output of the raft partitions command for ONOS.
3618 """
Jon Hall61282e32015-03-19 11:34:11 -07003619 # Sample JSON
3620 # {
3621 # "leader": "tcp://10.128.30.11:7238",
3622 # "members": [
3623 # "tcp://10.128.30.11:7238",
3624 # "tcp://10.128.30.17:7238",
3625 # "tcp://10.128.30.13:7238",
3626 # ],
3627 # "name": "p1",
3628 # "term": 3
3629 # },
Jon Hall63604932015-02-26 17:09:50 -08003630 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003631 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003632 if candidates:
3633 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003634 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003635 cmdStr += " -j"
3636 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003637 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003638 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003639 return output
Jon Hallc6793552016-01-19 14:18:37 -08003640 except AssertionError:
3641 main.log.exception( "" )
3642 return None
Jon Hall63604932015-02-26 17:09:50 -08003643 except TypeError:
3644 main.log.exception( self.name + ": Object not as expected" )
3645 return None
3646 except pexpect.EOF:
3647 main.log.error( self.name + ": EOF exception found" )
3648 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003649 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003650 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003651 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003652 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003653
Jon Halle9f909e2016-09-23 10:43:12 -07003654 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003655 """
3656 Returns the output of the apps command for ONOS. This command lists
3657 information about installed ONOS applications
3658 """
3659 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003660 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003661 # "description":"ONOS OpenFlow protocol southbound providers",
3662 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003663 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003664 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003665 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003666 if summary:
3667 cmdStr += " -s"
3668 if active:
3669 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003670 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003671 cmdStr += " -j"
3672 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003673 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003674 assert "Command not found:" not in output, output
3675 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003676 return output
Jon Hallbe379602015-03-24 13:39:32 -07003677 # FIXME: look at specific exceptions/Errors
3678 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003679 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003680 return None
3681 except TypeError:
3682 main.log.exception( self.name + ": Object not as expected" )
3683 return None
3684 except pexpect.EOF:
3685 main.log.error( self.name + ": EOF exception found" )
3686 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003687 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003688 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003689 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003690 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003691
Jon Hall146f1522015-03-24 15:33:24 -07003692 def appStatus( self, appName ):
3693 """
3694 Uses the onos:apps cli command to return the status of an application.
3695 Returns:
3696 "ACTIVE" - If app is installed and activated
3697 "INSTALLED" - If app is installed and deactivated
3698 "UNINSTALLED" - If app is not installed
3699 None - on error
3700 """
Jon Hall146f1522015-03-24 15:33:24 -07003701 try:
3702 if not isinstance( appName, types.StringType ):
3703 main.log.error( self.name + ".appStatus(): appName must be" +
3704 " a string" )
3705 return None
3706 output = self.apps( jsonFormat=True )
3707 appsJson = json.loads( output )
3708 state = None
3709 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003710 if appName == app.get( 'name' ):
3711 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003712 break
3713 if state == "ACTIVE" or state == "INSTALLED":
3714 return state
3715 elif state is None:
Jon Hall8bafdc02017-09-05 11:36:26 -07003716 main.log.warn( "{} app not found", appName )
Jon Hall146f1522015-03-24 15:33:24 -07003717 return "UNINSTALLED"
3718 elif state:
3719 main.log.error( "Unexpected state from 'onos:apps': " +
3720 str( state ) )
3721 return state
Jon Hallc6793552016-01-19 14:18:37 -08003722 except ( TypeError, ValueError ):
3723 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003724 return None
3725 except pexpect.EOF:
3726 main.log.error( self.name + ": EOF exception found" )
3727 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003728 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003729 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003730 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003731 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003732
Jon Hallbe379602015-03-24 13:39:32 -07003733 def app( self, appName, option ):
3734 """
3735 Interacts with the app command for ONOS. This command manages
3736 application inventory.
3737 """
Jon Hallbe379602015-03-24 13:39:32 -07003738 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003739 # Validate argument types
3740 valid = True
3741 if not isinstance( appName, types.StringType ):
3742 main.log.error( self.name + ".app(): appName must be a " +
3743 "string" )
3744 valid = False
3745 if not isinstance( option, types.StringType ):
3746 main.log.error( self.name + ".app(): option must be a string" )
3747 valid = False
3748 if not valid:
3749 return main.FALSE
3750 # Validate Option
3751 option = option.lower()
3752 # NOTE: Install may become a valid option
3753 if option == "activate":
3754 pass
3755 elif option == "deactivate":
3756 pass
3757 elif option == "uninstall":
3758 pass
3759 else:
3760 # Invalid option
3761 main.log.error( "The ONOS app command argument only takes " +
3762 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003763 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003764 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003765 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003766 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003767 assert output is not None, "Error in sendline"
3768 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003769 if "Error executing command" in output:
3770 main.log.error( "Error in processing onos:app command: " +
3771 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003772 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003773 elif "No such application" in output:
3774 main.log.error( "The application '" + appName +
3775 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003776 return main.FALSE
3777 elif "Command not found:" in output:
3778 main.log.error( "Error in processing onos:app command: " +
3779 str( output ) )
3780 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003781 elif "Unsupported command:" in output:
3782 main.log.error( "Incorrect command given to 'app': " +
3783 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003784 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003785 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003786 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003787 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003788 except AssertionError:
3789 main.log.exception( self.name + ": AssertionError exception found" )
3790 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003791 except TypeError:
3792 main.log.exception( self.name + ": Object not as expected" )
3793 return main.ERROR
3794 except pexpect.EOF:
3795 main.log.error( self.name + ": EOF exception found" )
3796 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003797 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003798 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003799 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003800 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003801
Jon Hallbd16b922015-03-26 17:53:15 -07003802 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003803 """
3804 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003805 appName is the hierarchical app name, not the feature name
3806 If check is True, method will check the status of the app after the
3807 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003808 Returns main.TRUE if the command was successfully sent
3809 main.FALSE if the cli responded with an error or given
3810 incorrect input
3811 """
3812 try:
3813 if not isinstance( appName, types.StringType ):
3814 main.log.error( self.name + ".activateApp(): appName must be" +
3815 " a string" )
3816 return main.FALSE
3817 status = self.appStatus( appName )
3818 if status == "INSTALLED":
3819 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003820 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003821 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003822 status = self.appStatus( appName )
3823 if status == "ACTIVE":
3824 return main.TRUE
3825 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003826 main.log.debug( "The state of application " +
3827 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003828 time.sleep( 1 )
3829 return main.FALSE
3830 else: # not 'check' or command didn't succeed
3831 return response
Jon Hall146f1522015-03-24 15:33:24 -07003832 elif status == "ACTIVE":
3833 return main.TRUE
3834 elif status == "UNINSTALLED":
3835 main.log.error( self.name + ": Tried to activate the " +
3836 "application '" + appName + "' which is not " +
3837 "installed." )
3838 else:
3839 main.log.error( "Unexpected return value from appStatus: " +
3840 str( status ) )
3841 return main.ERROR
3842 except TypeError:
3843 main.log.exception( self.name + ": Object not as expected" )
3844 return main.ERROR
3845 except pexpect.EOF:
3846 main.log.error( self.name + ": EOF exception found" )
3847 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003848 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003849 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003850 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003851 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003852
Jon Hallbd16b922015-03-26 17:53:15 -07003853 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003854 """
3855 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003856 appName is the hierarchical app name, not the feature name
3857 If check is True, method will check the status of the app after the
3858 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003859 Returns main.TRUE if the command was successfully sent
3860 main.FALSE if the cli responded with an error or given
3861 incorrect input
3862 """
3863 try:
3864 if not isinstance( appName, types.StringType ):
3865 main.log.error( self.name + ".deactivateApp(): appName must " +
3866 "be a string" )
3867 return main.FALSE
3868 status = self.appStatus( appName )
3869 if status == "INSTALLED":
3870 return main.TRUE
3871 elif status == "ACTIVE":
3872 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003873 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003874 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003875 status = self.appStatus( appName )
3876 if status == "INSTALLED":
3877 return main.TRUE
3878 else:
3879 time.sleep( 1 )
3880 return main.FALSE
3881 else: # not check or command didn't succeed
3882 return response
Jon Hall146f1522015-03-24 15:33:24 -07003883 elif status == "UNINSTALLED":
3884 main.log.warn( self.name + ": Tried to deactivate the " +
3885 "application '" + appName + "' which is not " +
3886 "installed." )
3887 return main.TRUE
3888 else:
3889 main.log.error( "Unexpected return value from appStatus: " +
3890 str( status ) )
3891 return main.ERROR
3892 except TypeError:
3893 main.log.exception( self.name + ": Object not as expected" )
3894 return main.ERROR
3895 except pexpect.EOF:
3896 main.log.error( self.name + ": EOF exception found" )
3897 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003898 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003899 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003900 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003901 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003902
Jon Hallbd16b922015-03-26 17:53:15 -07003903 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003904 """
3905 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003906 appName is the hierarchical app name, not the feature name
3907 If check is True, method will check the status of the app after the
3908 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003909 Returns main.TRUE if the command was successfully sent
3910 main.FALSE if the cli responded with an error or given
3911 incorrect input
3912 """
3913 # TODO: check with Thomas about the state machine for apps
3914 try:
3915 if not isinstance( appName, types.StringType ):
3916 main.log.error( self.name + ".uninstallApp(): appName must " +
3917 "be a string" )
3918 return main.FALSE
3919 status = self.appStatus( appName )
3920 if status == "INSTALLED":
3921 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003922 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003923 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003924 status = self.appStatus( appName )
3925 if status == "UNINSTALLED":
3926 return main.TRUE
3927 else:
3928 time.sleep( 1 )
3929 return main.FALSE
3930 else: # not check or command didn't succeed
3931 return response
Jon Hall146f1522015-03-24 15:33:24 -07003932 elif status == "ACTIVE":
3933 main.log.warn( self.name + ": Tried to uninstall the " +
3934 "application '" + appName + "' which is " +
3935 "currently active." )
3936 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003937 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003938 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003939 status = self.appStatus( appName )
3940 if status == "UNINSTALLED":
3941 return main.TRUE
3942 else:
3943 time.sleep( 1 )
3944 return main.FALSE
3945 else: # not check or command didn't succeed
3946 return response
Jon Hall146f1522015-03-24 15:33:24 -07003947 elif status == "UNINSTALLED":
3948 return main.TRUE
3949 else:
3950 main.log.error( "Unexpected return value from appStatus: " +
3951 str( status ) )
3952 return main.ERROR
3953 except TypeError:
3954 main.log.exception( self.name + ": Object not as expected" )
3955 return main.ERROR
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 Hall146f1522015-03-24 15:33:24 -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 appIDs( self, jsonFormat=True ):
3965 """
3966 Show the mappings between app id and app names given by the 'app-ids'
3967 cli command
3968 """
3969 try:
3970 cmdStr = "app-ids"
3971 if jsonFormat:
3972 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003973 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003974 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003975 assert "Command not found:" not in output, output
3976 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003977 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003978 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003979 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003980 return None
3981 except TypeError:
3982 main.log.exception( self.name + ": Object not as expected" )
3983 return None
3984 except pexpect.EOF:
3985 main.log.error( self.name + ": EOF exception found" )
3986 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003987 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003988 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003989 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003990 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003991
3992 def appToIDCheck( self ):
3993 """
3994 This method will check that each application's ID listed in 'apps' is
3995 the same as the ID listed in 'app-ids'. The check will also check that
3996 there are no duplicate IDs issued. Note that an app ID should be
3997 a globaly unique numerical identifier for app/app-like features. Once
3998 an ID is registered, the ID is never freed up so that if an app is
3999 reinstalled it will have the same ID.
4000
4001 Returns: main.TRUE if the check passes and
4002 main.FALSE if the check fails or
4003 main.ERROR if there is some error in processing the test
4004 """
4005 try:
Jon Hall390696c2015-05-05 17:13:41 -07004006 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08004007 rawJson = self.appIDs( jsonFormat=True )
4008 if rawJson:
4009 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004010 else:
Jon Hallc6793552016-01-19 14:18:37 -08004011 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004012 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08004013 rawJson = self.apps( jsonFormat=True )
4014 if rawJson:
4015 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07004016 else:
Jon Hallc6793552016-01-19 14:18:37 -08004017 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07004018 bail = True
4019 if bail:
4020 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004021 result = main.TRUE
4022 for app in apps:
4023 appID = app.get( 'id' )
4024 if appID is None:
4025 main.log.error( "Error parsing app: " + str( app ) )
4026 result = main.FALSE
4027 appName = app.get( 'name' )
4028 if appName is None:
4029 main.log.error( "Error parsing app: " + str( app ) )
4030 result = main.FALSE
4031 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07004032 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hallbd16b922015-03-26 17:53:15 -07004033 if not current: # if ids doesn't have this id
4034 result = main.FALSE
4035 main.log.error( "'app-ids' does not have the ID for " +
4036 str( appName ) + " that apps does." )
Jon Hallb9d381e2018-02-05 12:02:10 -08004037 main.log.debug( "apps command returned: " + str( app ) +
4038 "; app-ids has: " + str( ids ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004039 elif len( current ) > 1:
4040 # there is more than one app with this ID
4041 result = main.FALSE
4042 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004043 elif not current[ 0 ][ 'name' ] == appName:
4044 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07004045 result = main.FALSE
4046 main.log.error( "'app-ids' has " + str( currentName ) +
4047 " registered under id:" + str( appID ) +
4048 " but 'apps' has " + str( appName ) )
4049 else:
4050 pass # id and name match!
4051 # now make sure that app-ids has no duplicates
4052 idsList = []
4053 namesList = []
4054 for item in ids:
4055 idsList.append( item[ 'id' ] )
4056 namesList.append( item[ 'name' ] )
4057 if len( idsList ) != len( set( idsList ) ) or\
4058 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004059 main.log.error( "'app-ids' has some duplicate entries: \n"
4060 + json.dumps( ids,
4061 sort_keys=True,
4062 indent=4,
4063 separators=( ',', ': ' ) ) )
4064 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07004065 return result
Jon Hallc6793552016-01-19 14:18:37 -08004066 except ( TypeError, ValueError ):
4067 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07004068 return main.ERROR
4069 except pexpect.EOF:
4070 main.log.error( self.name + ": EOF exception found" )
4071 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004072 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07004073 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07004074 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004075 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07004076
Jon Hallfb760a02015-04-13 15:35:03 -07004077 def getCfg( self, component=None, propName=None, short=False,
4078 jsonFormat=True ):
4079 """
4080 Get configuration settings from onos cli
4081 Optional arguments:
4082 component - Optionally only list configurations for a specific
4083 component. If None, all components with configurations
4084 are displayed. Case Sensitive string.
4085 propName - If component is specified, propName option will show
4086 only this specific configuration from that component.
4087 Case Sensitive string.
4088 jsonFormat - Returns output as json. Note that this will override
4089 the short option
4090 short - Short, less verbose, version of configurations.
4091 This is overridden by the json option
4092 returns:
4093 Output from cli as a string or None on error
4094 """
4095 try:
4096 baseStr = "cfg"
4097 cmdStr = " get"
4098 componentStr = ""
4099 if component:
4100 componentStr += " " + component
4101 if propName:
4102 componentStr += " " + propName
4103 if jsonFormat:
4104 baseStr += " -j"
4105 elif short:
4106 baseStr += " -s"
4107 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004108 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004109 assert "Command not found:" not in output, output
4110 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004111 return output
4112 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004113 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004114 return None
4115 except TypeError:
4116 main.log.exception( self.name + ": Object not as expected" )
4117 return None
4118 except pexpect.EOF:
4119 main.log.error( self.name + ": EOF exception found" )
4120 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004121 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004122 except Exception:
4123 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004124 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004125
4126 def setCfg( self, component, propName, value=None, check=True ):
4127 """
4128 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004129 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004130 component - The case sensitive name of the component whose
4131 property is to be set
4132 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004133 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004134 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004135 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07004136 check - Boolean, Check whether the option was successfully set this
4137 only applies when a value is given.
4138 returns:
4139 main.TRUE on success or main.FALSE on failure. If check is False,
4140 will return main.TRUE unless there is an error
4141 """
4142 try:
4143 baseStr = "cfg"
4144 cmdStr = " set " + str( component ) + " " + str( propName )
4145 if value is not None:
4146 cmdStr += " " + str( value )
4147 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004148 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004149 assert "Command not found:" not in output, output
4150 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004151 if value and check:
4152 results = self.getCfg( component=str( component ),
4153 propName=str( propName ),
4154 jsonFormat=True )
4155 # Check if current value is what we just set
4156 try:
4157 jsonOutput = json.loads( results )
4158 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004159 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004160 main.log.exception( "Error parsing cfg output" )
4161 main.log.error( "output:" + repr( results ) )
4162 return main.FALSE
4163 if current == str( value ):
4164 return main.TRUE
4165 return main.FALSE
4166 return main.TRUE
4167 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004168 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004169 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004170 except ( TypeError, ValueError ):
4171 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004172 return main.FALSE
4173 except pexpect.EOF:
4174 main.log.error( self.name + ": EOF exception found" )
4175 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004176 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004177 except Exception:
4178 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004179 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07004180
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004181 def distPrimitivesSend( self, cmd ):
4182 """
4183 Function to handle sending cli commands for the distributed primitives test app
4184
4185 This command will catch some exceptions and retry the command on some
4186 specific store exceptions.
4187
4188 Required arguments:
4189 cmd - The command to send to the cli
4190 returns:
4191 string containing the cli output
4192 None on Error
4193 """
4194 try:
4195 output = self.sendline( cmd )
4196 try:
4197 assert output is not None, "Error in sendline"
4198 # TODO: Maybe make this less hardcoded
4199 # ConsistentMap Exceptions
4200 assert "org.onosproject.store.service" not in output
4201 # Node not leader
4202 assert "java.lang.IllegalStateException" not in output
4203 except AssertionError:
4204 main.log.error( "Error in processing '" + cmd + "' " +
4205 "command: " + str( output ) )
4206 retryTime = 30 # Conservative time, given by Madan
4207 main.log.info( "Waiting " + str( retryTime ) +
4208 "seconds before retrying." )
4209 time.sleep( retryTime ) # Due to change in mastership
4210 output = self.sendline( cmd )
4211 assert output is not None, "Error in sendline"
4212 assert "Command not found:" not in output, output
4213 assert "Error executing command" not in output, output
4214 main.log.info( self.name + ": " + output )
4215 return output
4216 except AssertionError:
4217 main.log.exception( "Error in processing '" + cmd + "' command." )
4218 return None
4219 except TypeError:
4220 main.log.exception( self.name + ": Object not as expected" )
4221 return None
4222 except pexpect.EOF:
4223 main.log.error( self.name + ": EOF exception found" )
4224 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004225 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004226 except Exception:
4227 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004228 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004229
Jon Hall390696c2015-05-05 17:13:41 -07004230 def setTestAdd( self, setName, values ):
4231 """
4232 CLI command to add elements to a distributed set.
4233 Arguments:
4234 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004235 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004236 Example usages:
4237 setTestAdd( "set1", "a b c" )
4238 setTestAdd( "set2", "1" )
4239 returns:
4240 main.TRUE on success OR
4241 main.FALSE if elements were already in the set OR
4242 main.ERROR on error
4243 """
4244 try:
4245 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004246 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004247 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4248 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004249 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004250 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004251 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004252 return main.FALSE
4253 else:
4254 main.log.error( self.name + ": setTestAdd did not" +
4255 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004256 main.log.debug( self.name + " actual: " + repr( output ) )
4257 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004258 except TypeError:
4259 main.log.exception( self.name + ": Object not as expected" )
4260 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004261 except Exception:
4262 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004263 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004264
4265 def setTestRemove( self, setName, values, clear=False, retain=False ):
4266 """
4267 CLI command to remove elements from a distributed set.
4268 Required arguments:
4269 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004270 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004271 Optional arguments:
4272 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004273 retain - Retain only the given values. (intersection of the
4274 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004275 returns:
4276 main.TRUE on success OR
4277 main.FALSE if the set was not changed OR
4278 main.ERROR on error
4279 """
4280 try:
4281 cmdStr = "set-test-remove "
4282 if clear:
4283 cmdStr += "-c " + str( setName )
4284 elif retain:
4285 cmdStr += "-r " + str( setName ) + " " + str( values )
4286 else:
4287 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004288 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004289 if clear:
4290 pattern = "Set " + str( setName ) + " cleared"
4291 if re.search( pattern, output ):
4292 return main.TRUE
4293 elif retain:
4294 positivePattern = str( setName ) + " was pruned to contain " +\
4295 "only elements of set \[(.*)\]"
4296 negativePattern = str( setName ) + " was not changed by " +\
4297 "retaining only elements of the set " +\
4298 "\[(.*)\]"
4299 if re.search( positivePattern, output ):
4300 return main.TRUE
4301 elif re.search( negativePattern, output ):
4302 return main.FALSE
4303 else:
4304 positivePattern = "\[(.*)\] was removed from the set " +\
4305 str( setName )
4306 if ( len( values.split() ) == 1 ):
4307 negativePattern = "\[(.*)\] was not in set " +\
4308 str( setName )
4309 else:
4310 negativePattern = "No element of \[(.*)\] was in set " +\
4311 str( setName )
4312 if re.search( positivePattern, output ):
4313 return main.TRUE
4314 elif re.search( negativePattern, output ):
4315 return main.FALSE
4316 main.log.error( self.name + ": setTestRemove did not" +
4317 " match expected output" )
4318 main.log.debug( self.name + " expected: " + pattern )
4319 main.log.debug( self.name + " actual: " + repr( output ) )
4320 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004321 except TypeError:
4322 main.log.exception( self.name + ": Object not as expected" )
4323 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004324 except Exception:
4325 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004326 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004327
4328 def setTestGet( self, setName, values="" ):
4329 """
4330 CLI command to get the elements in a distributed set.
4331 Required arguments:
4332 setName - The name of the set to remove from.
4333 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004334 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004335 returns:
4336 main.ERROR on error OR
4337 A list of elements in the set if no optional arguments are
4338 supplied OR
4339 A tuple containing the list then:
4340 main.FALSE if the given values are not in the set OR
4341 main.TRUE if the given values are in the set OR
4342 """
4343 try:
4344 values = str( values ).strip()
4345 setName = str( setName ).strip()
4346 length = len( values.split() )
4347 containsCheck = None
4348 # Patterns to match
4349 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004350 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004351 containsTrue = "Set " + setName + " contains the value " + values
4352 containsFalse = "Set " + setName + " did not contain the value " +\
4353 values
4354 containsAllTrue = "Set " + setName + " contains the the subset " +\
4355 setPattern
4356 containsAllFalse = "Set " + setName + " did not contain the the" +\
4357 " subset " + setPattern
4358
4359 cmdStr = "set-test-get "
4360 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004361 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004362 if length == 0:
4363 match = re.search( pattern, output )
4364 else: # if given values
4365 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004366 patternTrue = pattern + "\r\n" + containsTrue
4367 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004368 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004369 patternTrue = pattern + "\r\n" + containsAllTrue
4370 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004371 matchTrue = re.search( patternTrue, output )
4372 matchFalse = re.search( patternFalse, output )
4373 if matchTrue:
4374 containsCheck = main.TRUE
4375 match = matchTrue
4376 elif matchFalse:
4377 containsCheck = main.FALSE
4378 match = matchFalse
4379 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004380 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004381 "expected output" )
4382 main.log.debug( self.name + " expected: " + pattern )
4383 main.log.debug( self.name + " actual: " + repr( output ) )
4384 match = None
4385 if match:
4386 setMatch = match.group( 1 )
4387 if setMatch == '':
4388 setList = []
4389 else:
4390 setList = setMatch.split( ", " )
4391 if length > 0:
4392 return ( setList, containsCheck )
4393 else:
4394 return setList
4395 else: # no match
4396 main.log.error( self.name + ": setTestGet did not" +
4397 " match expected output" )
4398 main.log.debug( self.name + " expected: " + pattern )
4399 main.log.debug( self.name + " actual: " + repr( output ) )
4400 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004401 except TypeError:
4402 main.log.exception( self.name + ": Object not as expected" )
4403 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004404 except Exception:
4405 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004406 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004407
4408 def setTestSize( self, setName ):
4409 """
4410 CLI command to get the elements in a distributed set.
4411 Required arguments:
4412 setName - The name of the set to remove from.
4413 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004414 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004415 None on error
4416 """
4417 try:
4418 # TODO: Should this check against the number of elements returned
4419 # and then return true/false based on that?
4420 setName = str( setName ).strip()
4421 # Patterns to match
4422 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004423 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004424 setPattern
4425 cmdStr = "set-test-get -s "
4426 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004427 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004428 match = re.search( pattern, output )
4429 if match:
4430 setSize = int( match.group( 1 ) )
4431 setMatch = match.group( 2 )
4432 if len( setMatch.split() ) == setSize:
4433 main.log.info( "The size returned by " + self.name +
4434 " matches the number of elements in " +
4435 "the returned set" )
4436 else:
4437 main.log.error( "The size returned by " + self.name +
4438 " does not match the number of " +
4439 "elements in the returned set." )
4440 return setSize
4441 else: # no match
4442 main.log.error( self.name + ": setTestGet did not" +
4443 " match expected output" )
4444 main.log.debug( self.name + " expected: " + pattern )
4445 main.log.debug( self.name + " actual: " + repr( output ) )
4446 return None
Jon Hall390696c2015-05-05 17:13:41 -07004447 except TypeError:
4448 main.log.exception( self.name + ": Object not as expected" )
4449 return None
Jon Hall390696c2015-05-05 17:13:41 -07004450 except Exception:
4451 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004452 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004453
Jon Hall80daded2015-05-27 16:07:00 -07004454 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004455 """
4456 Command to list the various counters in the system.
4457 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004458 if jsonFormat, a string of the json object returned by the cli
4459 command
4460 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004461 None on error
4462 """
Jon Hall390696c2015-05-05 17:13:41 -07004463 try:
Jon Hall390696c2015-05-05 17:13:41 -07004464 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004465 if jsonFormat:
4466 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004467 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004468 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004469 assert "Command not found:" not in output, output
4470 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004471 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004472 return output
Jon Hall390696c2015-05-05 17:13:41 -07004473 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004474 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004475 return None
Jon Hall390696c2015-05-05 17:13:41 -07004476 except TypeError:
4477 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004478 return None
Jon Hall390696c2015-05-05 17:13:41 -07004479 except pexpect.EOF:
4480 main.log.error( self.name + ": EOF exception found" )
4481 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004482 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004483 except Exception:
4484 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004485 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004486
Jon Hall935db192016-04-19 00:22:04 -07004487 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004488 """
Jon Halle1a3b752015-07-22 13:02:46 -07004489 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004490 Required arguments:
4491 counter - The name of the counter to increment.
4492 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004493 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004494 returns:
4495 integer value of the counter or
4496 None on Error
4497 """
4498 try:
4499 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004500 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004501 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004502 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004503 if delta != 1:
4504 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004505 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004506 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004507 match = re.search( pattern, output )
4508 if match:
4509 return int( match.group( 1 ) )
4510 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004511 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004512 " match expected output." )
4513 main.log.debug( self.name + " expected: " + pattern )
4514 main.log.debug( self.name + " actual: " + repr( output ) )
4515 return None
Jon Hall390696c2015-05-05 17:13:41 -07004516 except TypeError:
4517 main.log.exception( self.name + ": Object not as expected" )
4518 return None
Jon Hall390696c2015-05-05 17:13:41 -07004519 except Exception:
4520 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004521 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004522
Jon Hall935db192016-04-19 00:22:04 -07004523 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004524 """
4525 CLI command to get a distributed counter then add a delta to it.
4526 Required arguments:
4527 counter - The name of the counter to increment.
4528 Optional arguments:
4529 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004530 returns:
4531 integer value of the counter or
4532 None on Error
4533 """
4534 try:
4535 counter = str( counter )
4536 delta = int( delta )
4537 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004538 cmdStr += counter
4539 if delta != 1:
4540 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004541 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004542 pattern = counter + " was updated to (-?\d+)"
4543 match = re.search( pattern, output )
4544 if match:
4545 return int( match.group( 1 ) )
4546 else:
4547 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4548 " match expected output." )
4549 main.log.debug( self.name + " expected: " + pattern )
4550 main.log.debug( self.name + " actual: " + repr( output ) )
4551 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004552 except TypeError:
4553 main.log.exception( self.name + ": Object not as expected" )
4554 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004555 except Exception:
4556 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004557 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004558
4559 def valueTestGet( self, valueName ):
4560 """
4561 CLI command to get the value of an atomic value.
4562 Required arguments:
4563 valueName - The name of the value to get.
4564 returns:
4565 string value of the value or
4566 None on Error
4567 """
4568 try:
4569 valueName = str( valueName )
4570 cmdStr = "value-test "
4571 operation = "get"
4572 cmdStr = "value-test {} {}".format( valueName,
4573 operation )
4574 output = self.distPrimitivesSend( cmdStr )
4575 pattern = "(\w+)"
4576 match = re.search( pattern, output )
4577 if match:
4578 return match.group( 1 )
4579 else:
4580 main.log.error( self.name + ": valueTestGet did not" +
4581 " match expected output." )
4582 main.log.debug( self.name + " expected: " + pattern )
4583 main.log.debug( self.name + " actual: " + repr( output ) )
4584 return None
4585 except TypeError:
4586 main.log.exception( self.name + ": Object not as expected" )
4587 return None
4588 except Exception:
4589 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004590 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004591
4592 def valueTestSet( self, valueName, newValue ):
4593 """
4594 CLI command to set the value of an atomic value.
4595 Required arguments:
4596 valueName - The name of the value to set.
4597 newValue - The value to assign to the given value.
4598 returns:
4599 main.TRUE on success or
4600 main.ERROR on Error
4601 """
4602 try:
4603 valueName = str( valueName )
4604 newValue = str( newValue )
4605 operation = "set"
4606 cmdStr = "value-test {} {} {}".format( valueName,
4607 operation,
4608 newValue )
4609 output = self.distPrimitivesSend( cmdStr )
4610 if output is not None:
4611 return main.TRUE
4612 else:
4613 return main.ERROR
4614 except TypeError:
4615 main.log.exception( self.name + ": Object not as expected" )
4616 return main.ERROR
4617 except Exception:
4618 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004619 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004620
4621 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4622 """
4623 CLI command to compareAndSet the value of an atomic value.
4624 Required arguments:
4625 valueName - The name of the value.
4626 oldValue - Compare the current value of the atomic value to this
4627 newValue - If the value equals oldValue, set the value to newValue
4628 returns:
4629 main.TRUE on success or
4630 main.FALSE on failure or
4631 main.ERROR on Error
4632 """
4633 try:
4634 valueName = str( valueName )
4635 oldValue = str( oldValue )
4636 newValue = str( newValue )
4637 operation = "compareAndSet"
4638 cmdStr = "value-test {} {} {} {}".format( valueName,
4639 operation,
4640 oldValue,
4641 newValue )
4642 output = self.distPrimitivesSend( cmdStr )
4643 pattern = "(\w+)"
4644 match = re.search( pattern, output )
4645 if match:
4646 result = match.group( 1 )
4647 if result == "true":
4648 return main.TRUE
4649 elif result == "false":
4650 return main.FALSE
4651 else:
4652 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4653 " match expected output." )
4654 main.log.debug( self.name + " expected: " + pattern )
4655 main.log.debug( self.name + " actual: " + repr( output ) )
4656 return main.ERROR
4657 except TypeError:
4658 main.log.exception( self.name + ": Object not as expected" )
4659 return main.ERROR
4660 except Exception:
4661 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004662 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004663
4664 def valueTestGetAndSet( self, valueName, newValue ):
4665 """
4666 CLI command to getAndSet the value of an atomic value.
4667 Required arguments:
4668 valueName - The name of the value to get.
4669 newValue - The value to assign to the given value
4670 returns:
4671 string value of the value or
4672 None on Error
4673 """
4674 try:
4675 valueName = str( valueName )
4676 cmdStr = "value-test "
4677 operation = "getAndSet"
4678 cmdStr += valueName + " " + operation
4679 cmdStr = "value-test {} {} {}".format( valueName,
4680 operation,
4681 newValue )
4682 output = self.distPrimitivesSend( cmdStr )
4683 pattern = "(\w+)"
4684 match = re.search( pattern, output )
4685 if match:
4686 return match.group( 1 )
4687 else:
4688 main.log.error( self.name + ": valueTestGetAndSet did not" +
4689 " match expected output." )
4690 main.log.debug( self.name + " expected: " + pattern )
4691 main.log.debug( self.name + " actual: " + repr( output ) )
4692 return None
4693 except TypeError:
4694 main.log.exception( self.name + ": Object not as expected" )
4695 return None
4696 except Exception:
4697 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004698 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004699
4700 def valueTestDestroy( self, valueName ):
4701 """
4702 CLI command to destroy an atomic value.
4703 Required arguments:
4704 valueName - The name of the value to destroy.
4705 returns:
4706 main.TRUE on success or
4707 main.ERROR on Error
4708 """
4709 try:
4710 valueName = str( valueName )
4711 cmdStr = "value-test "
4712 operation = "destroy"
4713 cmdStr += valueName + " " + operation
4714 output = self.distPrimitivesSend( cmdStr )
4715 if output is not None:
4716 return main.TRUE
4717 else:
4718 return main.ERROR
4719 except TypeError:
4720 main.log.exception( self.name + ": Object not as expected" )
4721 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004722 except Exception:
4723 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004724 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004725
YPZhangfebf7302016-05-24 16:45:56 -07004726 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004727 """
4728 Description: Execute summary command in onos
4729 Returns: json object ( summary -j ), returns main.FALSE if there is
4730 no output
4731
4732 """
4733 try:
4734 cmdStr = "summary"
4735 if jsonFormat:
4736 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004737 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004738 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004739 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004740 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004741 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004742 if not handle:
4743 main.log.error( self.name + ": There is no output in " +
4744 "summary command" )
4745 return main.FALSE
4746 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004747 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004748 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004749 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004750 except TypeError:
4751 main.log.exception( self.name + ": Object not as expected" )
4752 return None
4753 except pexpect.EOF:
4754 main.log.error( self.name + ": EOF exception found" )
4755 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004756 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004757 except Exception:
4758 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004759 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004760
Jon Hall935db192016-04-19 00:22:04 -07004761 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004762 """
4763 CLI command to get the value of a key in a consistent map using
4764 transactions. This a test function and can only get keys from the
4765 test map hard coded into the cli command
4766 Required arguments:
4767 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004768 returns:
4769 The string value of the key or
4770 None on Error
4771 """
4772 try:
4773 keyName = str( keyName )
4774 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004775 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004776 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004777 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4778 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004779 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004780 return None
4781 else:
4782 match = re.search( pattern, output )
4783 if match:
4784 return match.groupdict()[ 'value' ]
4785 else:
4786 main.log.error( self.name + ": transactionlMapGet did not" +
4787 " match expected output." )
4788 main.log.debug( self.name + " expected: " + pattern )
4789 main.log.debug( self.name + " actual: " + repr( output ) )
4790 return None
4791 except TypeError:
4792 main.log.exception( self.name + ": Object not as expected" )
4793 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004794 except Exception:
4795 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004796 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004797
Jon Hall935db192016-04-19 00:22:04 -07004798 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004799 """
4800 CLI command to put a value into 'numKeys' number of keys in a
4801 consistent map using transactions. This a test function and can only
4802 put into keys named 'Key#' of the test map hard coded into the cli command
4803 Required arguments:
4804 numKeys - Number of keys to add the value to
4805 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004806 returns:
4807 A dictionary whose keys are the name of the keys put into the map
4808 and the values of the keys are dictionaries whose key-values are
4809 'value': value put into map and optionaly
4810 'oldValue': Previous value in the key or
4811 None on Error
4812
4813 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004814 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4815 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004816 """
4817 try:
4818 numKeys = str( numKeys )
4819 value = str( value )
4820 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004821 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004822 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004823 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4824 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4825 results = {}
4826 for line in output.splitlines():
4827 new = re.search( newPattern, line )
4828 updated = re.search( updatedPattern, line )
4829 if new:
4830 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4831 elif updated:
4832 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004833 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004834 else:
4835 main.log.error( self.name + ": transactionlMapGet did not" +
4836 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004837 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4838 newPattern,
4839 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004840 main.log.debug( self.name + " actual: " + repr( output ) )
4841 return results
4842 except TypeError:
4843 main.log.exception( self.name + ": Object not as expected" )
4844 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004845 except Exception:
4846 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004847 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004848
acsmarsdaea66c2015-09-03 11:44:06 -07004849 def maps( self, jsonFormat=True ):
4850 """
4851 Description: Returns result of onos:maps
4852 Optional:
4853 * jsonFormat: enable json formatting of output
4854 """
4855 try:
4856 cmdStr = "maps"
4857 if jsonFormat:
4858 cmdStr += " -j"
4859 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004860 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004861 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004862 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004863 except AssertionError:
4864 main.log.exception( "" )
4865 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004866 except TypeError:
4867 main.log.exception( self.name + ": Object not as expected" )
4868 return None
4869 except pexpect.EOF:
4870 main.log.error( self.name + ": EOF exception found" )
4871 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004872 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004873 except Exception:
4874 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004875 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004876
4877 def getSwController( self, uri, jsonFormat=True ):
4878 """
4879 Descrition: Gets the controller information from the device
4880 """
4881 try:
4882 cmd = "device-controllers "
4883 if jsonFormat:
4884 cmd += "-j "
4885 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004886 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004887 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004888 return response
Jon Hallc6793552016-01-19 14:18:37 -08004889 except AssertionError:
4890 main.log.exception( "" )
4891 return None
GlennRC050596c2015-11-18 17:06:41 -08004892 except TypeError:
4893 main.log.exception( self.name + ": Object not as expected" )
4894 return None
4895 except pexpect.EOF:
4896 main.log.error( self.name + ": EOF exception found" )
4897 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004898 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004899 except Exception:
4900 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004901 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004902
4903 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4904 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004905 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004906
4907 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004908 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08004909 ip - String or List: The ip address of the controller.
4910 This parameter can be formed in a couple of different ways.
4911 VALID:
4912 10.0.0.1 - just the ip address
4913 tcp:10.0.0.1 - the protocol and the ip address
4914 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4915 so that you can add controllers with different
4916 protocols and ports
4917 INVALID:
4918 10.0.0.1:6653 - this is not supported by ONOS
4919
4920 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4921 port - The port number.
4922 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4923
4924 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4925 """
4926 try:
4927 cmd = "device-setcontrollers"
4928
4929 if jsonFormat:
4930 cmd += " -j"
4931 cmd += " " + uri
4932 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004933 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08004934 for item in ip:
4935 if ":" in item:
4936 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004937 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08004938 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004939 elif "." in sitem[ 1 ]:
4940 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08004941 else:
4942 main.log.error( "Malformed entry: " + item )
4943 raise TypeError
4944 else:
4945 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004946 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004947 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004948 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004949 if "Error" in response:
4950 main.log.error( response )
4951 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004952 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004953 except AssertionError:
4954 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004955 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004956 except TypeError:
4957 main.log.exception( self.name + ": Object not as expected" )
4958 return main.FALSE
4959 except pexpect.EOF:
4960 main.log.error( self.name + ": EOF exception found" )
4961 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004962 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004963 except Exception:
4964 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004965 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004966
4967 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004968 '''
GlennRC20fc6522015-12-23 23:26:57 -08004969 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004970 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08004971 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004972 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08004973 Returns:
4974 Returns main.FALSE if an exception is thrown or an error is present
4975 in the response. Otherwise, returns main.TRUE.
4976 NOTE:
4977 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004978 '''
GlennRC20fc6522015-12-23 23:26:57 -08004979 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004980 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07004981 deviceStr = device
4982 device = []
4983 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004984
4985 for d in device:
4986 time.sleep( 1 )
4987 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004988 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004989 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004990 if "Error" in response:
4991 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4992 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004993 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004994 except AssertionError:
4995 main.log.exception( "" )
4996 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004997 except TypeError:
4998 main.log.exception( self.name + ": Object not as expected" )
4999 return main.FALSE
5000 except pexpect.EOF:
5001 main.log.error( self.name + ": EOF exception found" )
5002 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005003 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005004 except Exception:
5005 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005006 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005007
5008 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005009 '''
GlennRC20fc6522015-12-23 23:26:57 -08005010 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005011 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08005012 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005013 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08005014 Returns:
5015 Returns main.FALSE if an exception is thrown or an error is present
5016 in the response. Otherwise, returns main.TRUE.
5017 NOTE:
5018 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005019 '''
GlennRC20fc6522015-12-23 23:26:57 -08005020 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005021 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08005022 host = list( host )
5023
5024 for h in host:
5025 time.sleep( 1 )
5026 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07005027 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005028 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08005029 if "Error" in response:
5030 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
5031 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005032 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005033 except AssertionError:
5034 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005035 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08005036 except TypeError:
5037 main.log.exception( self.name + ": Object not as expected" )
5038 return main.FALSE
5039 except pexpect.EOF:
5040 main.log.error( self.name + ": EOF exception found" )
5041 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005042 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08005043 except Exception:
5044 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005045 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005046
YPZhangfebf7302016-05-24 16:45:56 -07005047 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005048 '''
GlennRCed771242016-01-13 17:02:47 -08005049 Description:
5050 Bring link down or up in the null-provider.
5051 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005052 begin - (string) One end of a device or switch.
5053 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08005054 returns:
5055 main.TRUE if no exceptions were thrown and no Errors are
5056 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005057 '''
GlennRCed771242016-01-13 17:02:47 -08005058 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005059 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005060 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005061 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005062 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005063 if "Error" in response or "Failure" in response:
5064 main.log.error( response )
5065 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005066 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005067 except AssertionError:
5068 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005069 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005070 except TypeError:
5071 main.log.exception( self.name + ": Object not as expected" )
5072 return main.FALSE
5073 except pexpect.EOF:
5074 main.log.error( self.name + ": EOF exception found" )
5075 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005076 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005077 except Exception:
5078 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005079 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08005080
Jon Hall2c8959e2016-12-16 12:17:34 -08005081 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005082 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005083 Description:
5084 Changes the state of port in an OF switch by means of the
5085 PORTSTATUS OF messages.
5086 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005087 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5088 port - (string) target port in the device. Ex: '2'
5089 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005090 returns:
5091 main.TRUE if no exceptions were thrown and no Errors are
5092 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005093 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07005094 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005095 state = state.lower()
5096 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005097 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005098 response = self.sendline( cmd, showResponse=True )
5099 assert response is not None, "Error in sendline"
5100 assert "Command not found:" not in response, response
5101 if "Error" in response or "Failure" in response:
5102 main.log.error( response )
5103 return main.FALSE
5104 return main.TRUE
5105 except AssertionError:
5106 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005107 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005108 except TypeError:
5109 main.log.exception( self.name + ": Object not as expected" )
5110 return main.FALSE
5111 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()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005118
5119 def logSet( self, level="INFO", app="org.onosproject" ):
5120 """
5121 Set the logging level to lvl for a specific app
5122 returns main.TRUE on success
5123 returns main.FALSE if Error occurred
5124 if noExit is True, TestON will not exit, but clean up
5125 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5126 Level defaults to INFO
5127 """
5128 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005129 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005130 self.handle.expect( "onos>" )
5131
5132 response = self.handle.before
5133 if re.search( "Error", response ):
5134 return main.FALSE
5135 return main.TRUE
5136 except pexpect.TIMEOUT:
5137 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07005138 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005139 except pexpect.EOF:
5140 main.log.error( self.name + ": EOF exception found" )
5141 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005142 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07005143 except Exception:
5144 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005145 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005146
5147 def getGraphDict( self, timeout=60, includeHost=False ):
5148 """
5149 Return a dictionary which describes the latest network topology data as a
5150 graph.
5151 An example of the dictionary:
5152 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5153 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5154 Each vertex should at least have an 'edges' attribute which describes the
5155 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005156 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07005157 list of attributes.
5158 An example of the edges dictionary:
5159 'edges': { vertex2: { 'port': ..., 'weight': ... },
5160 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005161 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07005162 in topology data.
5163 """
5164 graphDict = {}
5165 try:
5166 links = self.links()
5167 links = json.loads( links )
5168 devices = self.devices()
5169 devices = json.loads( devices )
5170 idToDevice = {}
5171 for device in devices:
5172 idToDevice[ device[ 'id' ] ] = device
5173 if includeHost:
5174 hosts = self.hosts()
5175 # FIXME: support 'includeHost' argument
5176 for link in links:
5177 nodeA = link[ 'src' ][ 'device' ]
5178 nodeB = link[ 'dst' ][ 'device' ]
5179 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005180 if nodeA not in graphDict.keys():
5181 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005182 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07005183 'type': idToDevice[ nodeA ][ 'type' ],
5184 'available': idToDevice[ nodeA ][ 'available' ],
5185 'role': idToDevice[ nodeA ][ 'role' ],
5186 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5187 'hw': idToDevice[ nodeA ][ 'hw' ],
5188 'sw': idToDevice[ nodeA ][ 'sw' ],
5189 'serial': idToDevice[ nodeA ][ 'serial' ],
5190 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005191 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005192 else:
5193 # Assert nodeB is not connected to any current links of nodeA
5194 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005195 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5196 'type': link[ 'type' ],
5197 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005198 return graphDict
5199 except ( TypeError, ValueError ):
5200 main.log.exception( self.name + ": Object not as expected" )
5201 return None
5202 except KeyError:
5203 main.log.exception( self.name + ": KeyError exception found" )
5204 return None
5205 except AssertionError:
5206 main.log.exception( self.name + ": AssertionError exception found" )
5207 return None
5208 except pexpect.EOF:
5209 main.log.error( self.name + ": EOF exception found" )
5210 main.log.error( self.name + ": " + self.handle.before )
5211 return None
5212 except Exception:
5213 main.log.exception( self.name + ": Uncaught exception!" )
5214 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005215
5216 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005217 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005218 Send command to check intent-perf summary
5219 Returns: dictionary for intent-perf summary
5220 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005221 '''
YPZhangcbc2a062016-07-11 10:55:44 -07005222 cmd = "intent-perf -s"
5223 respDic = {}
5224 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005225 assert resp is not None, "Error in sendline"
5226 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005227 try:
5228 # Generate the dictionary to return
5229 for l in resp.split( "\n" ):
5230 # Delete any white space in line
5231 temp = re.sub( r'\s+', '', l )
5232 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005233 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005234
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005235 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005236 main.log.exception( self.name + ": Object not as expected" )
5237 return None
5238 except KeyError:
5239 main.log.exception( self.name + ": KeyError exception found" )
5240 return None
5241 except AssertionError:
5242 main.log.exception( self.name + ": AssertionError exception found" )
5243 return None
5244 except pexpect.EOF:
5245 main.log.error( self.name + ": EOF exception found" )
5246 main.log.error( self.name + ": " + self.handle.before )
5247 return None
5248 except Exception:
5249 main.log.exception( self.name + ": Uncaught exception!" )
5250 return None
5251 return respDic
5252
Chiyu Chengec63bde2016-11-17 18:11:36 -08005253 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005254 """
5255 Searches the latest ONOS log file for the given search term and
5256 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005257
chengchiyu08303a02016-09-08 17:40:26 -07005258 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005259 searchTerm:
5260 The string to grep from the ONOS log.
5261 startLine:
5262 The term that decides which line is the start to search the searchTerm in
5263 the karaf log. For now, startTerm only works in 'first' mode.
5264 logNum:
5265 In some extreme cases, one karaf log is not big enough to contain all the
5266 information.Because of this, search mutiply logs is necessary to capture
5267 the right result. logNum is the number of karaf logs that we need to search
5268 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005269 mode:
5270 all: return all the strings that contain the search term
5271 last: return the last string that contains the search term
5272 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005273 num: return the number of times that the searchTerm appears in the log
5274 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005275 """
5276 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005277 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005278 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005279 logPath = '/opt/onos/log/karaf.log.'
5280 logPaths = '/opt/onos/log/karaf.log'
5281 for i in range( 1, logNum ):
5282 logPaths = logPath + str( i ) + " " + logPaths
5283 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005284 if startLine:
Jon Halla478b852017-12-04 15:00:15 -08005285 # 100000000 is just a extreme large number to make sure this function can
5286 # grep all the lines after startLine
You Wang6d301d42017-04-21 10:49:33 -07005287 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005288 if mode == 'all':
5289 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005290 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005291 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005292 elif mode == 'first':
5293 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5294 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005295 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005296 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005297 return num
You Wang6d301d42017-04-21 10:49:33 -07005298 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005299 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005300 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005301 else:
5302 main.log.error( self.name + " unsupported mode" )
5303 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005304 before = self.sendline( cmd )
5305 before = before.splitlines()
5306 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005307 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005308 return returnLines
5309 except AssertionError:
5310 main.log.error( self.name + " searchTerm is not string type" )
5311 return None
5312 except pexpect.EOF:
5313 main.log.error( self.name + ": EOF exception found" )
5314 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005315 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005316 except pexpect.TIMEOUT:
5317 main.log.error( self.name + ": TIMEOUT exception found" )
5318 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005319 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005320 except Exception:
5321 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005322 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005323
5324 def vplsShow( self, jsonFormat=True ):
5325 """
5326 Description: Returns result of onos:vpls show, which should list the
5327 configured VPLS networks and the assigned interfaces.
5328 Optional:
5329 * jsonFormat: enable json formatting of output
5330 Returns:
5331 The output of the command or None on error.
5332 """
5333 try:
5334 cmdStr = "vpls show"
5335 if jsonFormat:
5336 raise NotImplementedError
5337 cmdStr += " -j"
5338 handle = self.sendline( cmdStr )
5339 assert handle is not None, "Error in sendline"
5340 assert "Command not found:" not in handle, handle
5341 return handle
5342 except AssertionError:
5343 main.log.exception( "" )
5344 return None
5345 except TypeError:
5346 main.log.exception( self.name + ": Object not as expected" )
5347 return None
5348 except pexpect.EOF:
5349 main.log.error( self.name + ": EOF exception found" )
5350 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005351 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005352 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005353 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005354 return None
5355 except Exception:
5356 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005357 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005358
5359 def parseVplsShow( self ):
5360 """
5361 Parse the cli output of 'vpls show' into json output. This is required
5362 as there is currently no json output available.
5363 """
5364 try:
5365 output = []
5366 raw = self.vplsShow( jsonFormat=False )
5367 namePat = "VPLS name: (?P<name>\w+)"
5368 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5369 encapPat = "Encapsulation: (?P<encap>\w+)"
5370 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5371 mIter = re.finditer( pattern, raw )
5372 for match in mIter:
5373 item = {}
5374 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005375 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005376 if ifaces == [ "" ]:
5377 ifaces = []
5378 item[ 'interfaces' ] = ifaces
5379 encap = match.group( 'encap' )
5380 if encap != 'NONE':
5381 item[ 'encapsulation' ] = encap.lower()
5382 output.append( item )
5383 return output
5384 except Exception:
5385 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005386 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005387
5388 def vplsList( self, jsonFormat=True ):
5389 """
5390 Description: Returns result of onos:vpls list, which should list the
5391 configured VPLS networks.
5392 Optional:
5393 * jsonFormat: enable json formatting of output
5394 """
5395 try:
5396 cmdStr = "vpls list"
5397 if jsonFormat:
5398 raise NotImplementedError
5399 cmdStr += " -j"
5400 handle = self.sendline( cmdStr )
5401 assert handle is not None, "Error in sendline"
5402 assert "Command not found:" not in handle, handle
5403 return handle
5404 except AssertionError:
5405 main.log.exception( "" )
5406 return None
5407 except TypeError:
5408 main.log.exception( self.name + ": Object not as expected" )
5409 return None
5410 except pexpect.EOF:
5411 main.log.error( self.name + ": EOF exception found" )
5412 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005413 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005414 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005415 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005416 return None
5417 except Exception:
5418 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005419 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005420
5421 def vplsCreate( self, network ):
5422 """
5423 CLI command to create a new VPLS network.
5424 Required arguments:
5425 network - String name of the network to create.
5426 returns:
5427 main.TRUE on success and main.FALSE on failure
5428 """
5429 try:
5430 network = str( network )
5431 cmdStr = "vpls create "
5432 cmdStr += network
5433 output = self.sendline( cmdStr )
5434 assert output is not None, "Error in sendline"
5435 assert "Command not found:" not in output, output
5436 assert "Error executing command" not in output, output
5437 assert "VPLS already exists:" not in output, output
5438 return main.TRUE
5439 except AssertionError:
5440 main.log.exception( "" )
5441 return main.FALSE
5442 except TypeError:
5443 main.log.exception( self.name + ": Object not as expected" )
5444 return main.FALSE
5445 except pexpect.EOF:
5446 main.log.error( self.name + ": EOF exception found" )
5447 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005448 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005449 except Exception:
5450 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005451 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005452
5453 def vplsDelete( self, network ):
5454 """
5455 CLI command to delete a VPLS network.
5456 Required arguments:
5457 network - Name of the network to delete.
5458 returns:
5459 main.TRUE on success and main.FALSE on failure
5460 """
5461 try:
5462 network = str( network )
5463 cmdStr = "vpls delete "
5464 cmdStr += network
5465 output = self.sendline( cmdStr )
5466 assert output is not None, "Error in sendline"
5467 assert "Command not found:" not in output, output
5468 assert "Error executing command" not in output, output
5469 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005470 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005471 return main.TRUE
5472 except AssertionError:
5473 main.log.exception( "" )
5474 return main.FALSE
5475 except TypeError:
5476 main.log.exception( self.name + ": Object not as expected" )
5477 return main.FALSE
5478 except pexpect.EOF:
5479 main.log.error( self.name + ": EOF exception found" )
5480 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005481 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005482 except Exception:
5483 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005484 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005485
5486 def vplsAddIface( self, network, iface ):
5487 """
5488 CLI command to add an interface to a VPLS network.
5489 Required arguments:
5490 network - Name of the network to add the interface to.
5491 iface - The ONOS name for an interface.
5492 returns:
5493 main.TRUE on success and main.FALSE on failure
5494 """
5495 try:
5496 network = str( network )
5497 iface = str( iface )
5498 cmdStr = "vpls add-if "
5499 cmdStr += network + " " + iface
5500 output = self.sendline( cmdStr )
5501 assert output is not None, "Error in sendline"
5502 assert "Command not found:" not in output, output
5503 assert "Error executing command" not in output, output
5504 assert "already associated to network" not in output, output
5505 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005506 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005507 return main.TRUE
5508 except AssertionError:
5509 main.log.exception( "" )
5510 return main.FALSE
5511 except TypeError:
5512 main.log.exception( self.name + ": Object not as expected" )
5513 return main.FALSE
5514 except pexpect.EOF:
5515 main.log.error( self.name + ": EOF exception found" )
5516 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005517 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005518 except Exception:
5519 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005520 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005521
5522 def vplsRemIface( self, network, iface ):
5523 """
5524 CLI command to remove an interface from a VPLS network.
5525 Required arguments:
5526 network - Name of the network to remove the interface from.
5527 iface - Name of the interface to remove.
5528 returns:
5529 main.TRUE on success and main.FALSE on failure
5530 """
5531 try:
5532 iface = str( iface )
5533 cmdStr = "vpls rem-if "
5534 cmdStr += network + " " + iface
5535 output = self.sendline( cmdStr )
5536 assert output is not None, "Error in sendline"
5537 assert "Command not found:" not in output, output
5538 assert "Error executing command" not in output, output
5539 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005540 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005541 return main.TRUE
5542 except AssertionError:
5543 main.log.exception( "" )
5544 return main.FALSE
5545 except TypeError:
5546 main.log.exception( self.name + ": Object not as expected" )
5547 return main.FALSE
5548 except pexpect.EOF:
5549 main.log.error( self.name + ": EOF exception found" )
5550 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005551 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005552 except Exception:
5553 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005554 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005555
5556 def vplsClean( self ):
5557 """
5558 Description: Clears the VPLS app configuration.
5559 Returns: main.TRUE on success and main.FALSE on failure
5560 """
5561 try:
5562 cmdStr = "vpls clean"
5563 handle = self.sendline( cmdStr )
5564 assert handle is not None, "Error in sendline"
5565 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005566 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005567 return handle
5568 except AssertionError:
5569 main.log.exception( "" )
5570 return main.FALSE
5571 except TypeError:
5572 main.log.exception( self.name + ": Object not as expected" )
5573 return main.FALSE
5574 except pexpect.EOF:
5575 main.log.error( self.name + ": EOF exception found" )
5576 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005577 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005578 except Exception:
5579 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005580 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005581
5582 def vplsSetEncap( self, network, encapType ):
5583 """
5584 CLI command to add an interface to a VPLS network.
5585 Required arguments:
5586 network - Name of the network to create.
5587 encapType - Type of encapsulation.
5588 returns:
5589 main.TRUE on success and main.FALSE on failure
5590 """
5591 try:
5592 network = str( network )
5593 encapType = str( encapType ).upper()
5594 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5595 cmdStr = "vpls set-encap "
5596 cmdStr += network + " " + encapType
5597 output = self.sendline( cmdStr )
5598 assert output is not None, "Error in sendline"
5599 assert "Command not found:" not in output, output
5600 assert "Error executing command" not in output, output
5601 assert "already associated to network" not in output, output
5602 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005603 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005604 return main.TRUE
5605 except AssertionError:
5606 main.log.exception( "" )
5607 return main.FALSE
5608 except TypeError:
5609 main.log.exception( self.name + ": Object not as expected" )
5610 return main.FALSE
5611 except pexpect.EOF:
5612 main.log.error( self.name + ": EOF exception found" )
5613 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005614 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005615 except Exception:
5616 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005617 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005618
5619 def interfaces( self, jsonFormat=True ):
5620 """
5621 Description: Returns result of interfaces command.
5622 Optional:
5623 * jsonFormat: enable json formatting of output
5624 Returns:
5625 The output of the command or None on error.
5626 """
5627 try:
5628 cmdStr = "interfaces"
5629 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005630 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005631 cmdStr += " -j"
5632 handle = self.sendline( cmdStr )
5633 assert handle is not None, "Error in sendline"
5634 assert "Command not found:" not in handle, handle
5635 return handle
5636 except AssertionError:
5637 main.log.exception( "" )
5638 return None
5639 except TypeError:
5640 main.log.exception( self.name + ": Object not as expected" )
5641 return None
5642 except pexpect.EOF:
5643 main.log.error( self.name + ": EOF exception found" )
5644 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005645 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005646 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005647 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005648 return None
5649 except Exception:
5650 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005651 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005652
5653 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005654 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005655 Get the timestamp of searchTerm from karaf log.
5656
5657 Arguments:
5658 splitTerm_before and splitTerm_after:
5659
5660 The terms that split the string that contains the timeStamp of
5661 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5662 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5663 and the splitTerm_after is "x"
5664
5665 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005666 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005667 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005668 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005669 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005670 return main.ERROR
5671 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005672 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005673 main.log.warn( "Captured timestamp string is empty" )
5674 return main.ERROR
5675 lines = lines[ 0 ]
5676 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005677 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005678 # get the target value
5679 line = lines.split( splitTerm_before )
5680 key = line[ 1 ].split( splitTerm_after )
5681 return int( key[ 0 ] )
5682 except IndexError:
5683 main.log.warn( "Index Error!" )
5684 return main.ERROR
5685 except AssertionError:
5686 main.log.warn( "Search Term Not Found " )
5687 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005688
5689 def workQueueAdd( self, queueName, value ):
5690 """
5691 CLI command to add a string to the specified Work Queue.
5692 This function uses the distributed primitives test app, which
5693 gives some cli access to distributed primitives for testing
5694 purposes only.
5695
5696 Required arguments:
5697 queueName - The name of the queue to add to
5698 value - The value to add to the queue
5699 returns:
5700 main.TRUE on success, main.FALSE on failure and
5701 main.ERROR on error.
5702 """
5703 try:
5704 queueName = str( queueName )
5705 value = str( value )
5706 prefix = "work-queue-test"
5707 operation = "add"
5708 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5709 output = self.distPrimitivesSend( cmdStr )
5710 if "Invalid operation name" in output:
5711 main.log.warn( output )
5712 return main.ERROR
5713 elif "Done" in output:
5714 return main.TRUE
5715 except TypeError:
5716 main.log.exception( self.name + ": Object not as expected" )
5717 return main.ERROR
5718 except Exception:
5719 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005720 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005721
5722 def workQueueAddMultiple( self, queueName, value1, value2 ):
5723 """
5724 CLI command to add two strings to the specified Work Queue.
5725 This function uses the distributed primitives test app, which
5726 gives some cli access to distributed primitives for testing
5727 purposes only.
5728
5729 Required arguments:
5730 queueName - The name of the queue to add to
5731 value1 - The first value to add to the queue
5732 value2 - The second value to add to the queue
5733 returns:
5734 main.TRUE on success, main.FALSE on failure and
5735 main.ERROR on error.
5736 """
5737 try:
5738 queueName = str( queueName )
5739 value1 = str( value1 )
5740 value2 = str( value2 )
5741 prefix = "work-queue-test"
5742 operation = "addMultiple"
5743 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5744 output = self.distPrimitivesSend( cmdStr )
5745 if "Invalid operation name" in output:
5746 main.log.warn( output )
5747 return main.ERROR
5748 elif "Done" in output:
5749 return main.TRUE
5750 except TypeError:
5751 main.log.exception( self.name + ": Object not as expected" )
5752 return main.ERROR
5753 except Exception:
5754 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005755 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005756
5757 def workQueueTakeAndComplete( self, queueName, number=1 ):
5758 """
5759 CLI command to take a value from the specified Work Queue and compelte it.
5760 This function uses the distributed primitives test app, which
5761 gives some cli access to distributed primitives for testing
5762 purposes only.
5763
5764 Required arguments:
5765 queueName - The name of the queue to add to
5766 number - The number of items to take and complete
5767 returns:
5768 main.TRUE on success, main.FALSE on failure and
5769 main.ERROR on error.
5770 """
5771 try:
5772 queueName = str( queueName )
5773 number = str( int( number ) )
5774 prefix = "work-queue-test"
5775 operation = "takeAndComplete"
5776 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5777 output = self.distPrimitivesSend( cmdStr )
5778 if "Invalid operation name" in output:
5779 main.log.warn( output )
5780 return main.ERROR
5781 elif "Done" in output:
5782 return main.TRUE
5783 except TypeError:
5784 main.log.exception( self.name + ": Object not as expected" )
5785 return main.ERROR
5786 except Exception:
5787 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005788 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005789
5790 def workQueueDestroy( self, queueName ):
5791 """
5792 CLI command to destroy the specified Work Queue.
5793 This function uses the distributed primitives test app, which
5794 gives some cli access to distributed primitives for testing
5795 purposes only.
5796
5797 Required arguments:
5798 queueName - The name of the queue to add to
5799 returns:
5800 main.TRUE on success, main.FALSE on failure and
5801 main.ERROR on error.
5802 """
5803 try:
5804 queueName = str( queueName )
5805 prefix = "work-queue-test"
5806 operation = "destroy"
5807 cmdStr = " ".join( [ prefix, queueName, operation ] )
5808 output = self.distPrimitivesSend( cmdStr )
5809 if "Invalid operation name" in output:
5810 main.log.warn( output )
5811 return main.ERROR
5812 return main.TRUE
5813 except TypeError:
5814 main.log.exception( self.name + ": Object not as expected" )
5815 return main.ERROR
5816 except Exception:
5817 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005818 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005819
5820 def workQueueTotalPending( self, queueName ):
5821 """
5822 CLI command to get the Total Pending items of the specified Work Queue.
5823 This function uses the distributed primitives test app, which
5824 gives some cli access to distributed primitives for testing
5825 purposes only.
5826
5827 Required arguments:
5828 queueName - The name of the queue to add to
5829 returns:
5830 The number of Pending items in the specified work queue or
5831 None on error
5832 """
5833 try:
5834 queueName = str( queueName )
5835 prefix = "work-queue-test"
5836 operation = "totalPending"
5837 cmdStr = " ".join( [ prefix, queueName, operation ] )
5838 output = self.distPrimitivesSend( cmdStr )
5839 pattern = r'\d+'
5840 if "Invalid operation name" in output:
5841 main.log.warn( output )
5842 return None
5843 else:
5844 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005845 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005846 except ( AttributeError, TypeError ):
5847 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5848 return None
5849 except Exception:
5850 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005851 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005852
5853 def workQueueTotalCompleted( self, queueName ):
5854 """
5855 CLI command to get the Total Completed items of the specified Work Queue.
5856 This function uses the distributed primitives test app, which
5857 gives some cli access to distributed primitives for testing
5858 purposes only.
5859
5860 Required arguments:
5861 queueName - The name of the queue to add to
5862 returns:
5863 The number of complete items in the specified work queue or
5864 None on error
5865 """
5866 try:
5867 queueName = str( queueName )
5868 prefix = "work-queue-test"
5869 operation = "totalCompleted"
5870 cmdStr = " ".join( [ prefix, queueName, operation ] )
5871 output = self.distPrimitivesSend( cmdStr )
5872 pattern = r'\d+'
5873 if "Invalid operation name" in output:
5874 main.log.warn( output )
5875 return None
5876 else:
5877 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005878 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005879 except ( AttributeError, TypeError ):
5880 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5881 return None
5882 except Exception:
5883 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005884 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005885
5886 def workQueueTotalInProgress( self, queueName ):
5887 """
5888 CLI command to get the Total In Progress items of the specified Work Queue.
5889 This function uses the distributed primitives test app, which
5890 gives some cli access to distributed primitives for testing
5891 purposes only.
5892
5893 Required arguments:
5894 queueName - The name of the queue to add to
5895 returns:
5896 The number of In Progress items in the specified work queue or
5897 None on error
5898 """
5899 try:
5900 queueName = str( queueName )
5901 prefix = "work-queue-test"
5902 operation = "totalInProgress"
5903 cmdStr = " ".join( [ prefix, queueName, operation ] )
5904 output = self.distPrimitivesSend( cmdStr )
5905 pattern = r'\d+'
5906 if "Invalid operation name" in output:
5907 main.log.warn( output )
5908 return None
5909 else:
5910 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005911 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005912 except ( AttributeError, TypeError ):
5913 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5914 return None
5915 except Exception:
5916 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005917 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005918
5919 def events( self, args='-a' ):
5920 """
5921 Description: Returns events -a command output
5922 Optional:
5923 add other arguments
5924 """
5925 try:
5926 cmdStr = "events"
5927 if args:
5928 cmdStr += " " + args
5929 handle = self.sendline( cmdStr )
5930 assert handle is not None, "Error in sendline"
5931 assert "Command not found:" not in handle, handle
5932 return handle
5933 except AssertionError:
5934 main.log.exception( "" )
5935 return None
5936 except TypeError:
5937 main.log.exception( self.name + ": Object not as expected" )
5938 return None
5939 except pexpect.EOF:
5940 main.log.error( self.name + ": EOF exception found" )
5941 main.log.error( self.name + ": " + self.handle.before )
5942 main.cleanAndExit()
5943 except Exception:
5944 main.log.exception( self.name + ": Uncaught exception!" )
5945 main.cleanAndExit()
5946
5947 def getMaster( self, deviceID ):
5948 """
5949 Description: Obtains current master using "roles" command for a specific deviceID
5950 """
5951 try:
5952 return str( self.getRole( deviceID )[ 'master' ] )
5953 except AssertionError:
5954 main.log.exception( "" )
5955 return None
5956 except TypeError:
5957 main.log.exception( self.name + ": Object not as expected" )
5958 return None
5959 except pexpect.EOF:
5960 main.log.error( self.name + ": EOF exception found" )
5961 main.log.error( self.name + ": " + self.handle.before )
5962 main.cleanAndExit()
5963 except Exception:
5964 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07005965 main.cleanAndExit()
Jon Halla478b852017-12-04 15:00:15 -08005966
5967 def issu( self ):
5968 """
5969 Short summary of In-Service Software Upgrade status
5970
5971 Returns the output of the cli command or None on Error
5972 """
5973 try:
5974 cmdStr = "issu"
5975 handle = self.sendline( cmdStr )
5976 assert handle is not None, "Error in sendline"
5977 assert "Command not found:" not in handle, handle
5978 assert "Unsupported command:" not in handle, handle
5979 return handle
5980 except AssertionError:
5981 main.log.exception( "" )
5982 return None
5983 except TypeError:
5984 main.log.exception( self.name + ": Object not as expected" )
5985 return None
5986 except pexpect.EOF:
5987 main.log.error( self.name + ": EOF exception found" )
5988 main.log.error( self.name + ": " + self.handle.before )
5989 main.cleanAndExit()
5990 except Exception:
5991 main.log.exception( self.name + ": Uncaught exception!" )
5992 main.cleanAndExit()
5993
5994 def issuInit( self ):
5995 """
5996 Initiates an In-Service Software Upgrade
5997
5998 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
5999 """
6000 try:
6001 cmdStr = "issu init"
6002 handle = self.sendline( cmdStr )
6003 assert handle is not None, "Error in sendline"
6004 assert "Command not found:" not in handle, handle
6005 assert "Unsupported command:" not in handle, handle
6006 if "Initialized" in handle:
6007 return main.TRUE
6008 else:
6009 return main.FALSE
6010 except AssertionError:
6011 main.log.exception( "" )
6012 return main.ERROR
6013 except TypeError:
6014 main.log.exception( self.name + ": Object not as expected" )
6015 return main.ERROR
6016 except pexpect.EOF:
6017 main.log.error( self.name + ": EOF exception found" )
6018 main.log.error( self.name + ": " + self.handle.before )
6019 main.cleanAndExit()
6020 except Exception:
6021 main.log.exception( self.name + ": Uncaught exception!" )
6022 main.cleanAndExit()
6023
6024 def issuUpgrade( self ):
6025 """
6026 Transitions stores to upgraded nodes
6027
6028 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6029 """
6030 try:
6031 cmdStr = "issu upgrade"
6032 handle = self.sendline( cmdStr )
6033 assert handle is not None, "Error in sendline"
6034 assert "Command not found:" not in handle, handle
6035 assert "Unsupported command:" not in handle, handle
6036 if "Upgraded" in handle:
6037 return main.TRUE
6038 else:
6039 return main.FALSE
6040 except AssertionError:
6041 main.log.exception( "" )
6042 return main.ERROR
6043 except TypeError:
6044 main.log.exception( self.name + ": Object not as expected" )
6045 return main.ERROR
6046 except pexpect.EOF:
6047 main.log.error( self.name + ": EOF exception found" )
6048 main.log.error( self.name + ": " + self.handle.before )
6049 main.cleanAndExit()
6050 except Exception:
6051 main.log.exception( self.name + ": Uncaught exception!" )
6052 main.cleanAndExit()
6053
6054 def issuCommit( self ):
6055 """
6056 Finalizes an In-Service Software Upgrade
6057
6058 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6059 """
6060 try:
6061 cmdStr = "issu commit"
6062 handle = self.sendline( cmdStr )
6063 assert handle is not None, "Error in sendline"
6064 assert "Command not found:" not in handle, handle
6065 assert "Unsupported command:" not in handle, handle
6066 # TODO: Check the version returned by this command
6067 if "Committed version" in handle:
6068 return main.TRUE
6069 else:
6070 return main.FALSE
6071 except AssertionError:
6072 main.log.exception( "" )
6073 return main.ERROR
6074 except TypeError:
6075 main.log.exception( self.name + ": Object not as expected" )
6076 return main.ERROR
6077 except pexpect.EOF:
6078 main.log.error( self.name + ": EOF exception found" )
6079 main.log.error( self.name + ": " + self.handle.before )
6080 main.cleanAndExit()
6081 except Exception:
6082 main.log.exception( self.name + ": Uncaught exception!" )
6083 main.cleanAndExit()
6084
6085 def issuRollback( self ):
6086 """
6087 Rolls back an In-Service Software Upgrade
6088
6089 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6090 """
6091 try:
6092 cmdStr = "issu rollback"
6093 handle = self.sendline( cmdStr )
6094 assert handle is not None, "Error in sendline"
6095 assert "Command not found:" not in handle, handle
6096 assert "Unsupported command:" not in handle, handle
6097 # TODO: Check the version returned by this command
6098 if "Rolled back to version" in handle:
6099 return main.TRUE
6100 else:
6101 return main.FALSE
6102 except AssertionError:
6103 main.log.exception( "" )
6104 return main.ERROR
6105 except TypeError:
6106 main.log.exception( self.name + ": Object not as expected" )
6107 return main.ERROR
6108 except pexpect.EOF:
6109 main.log.error( self.name + ": EOF exception found" )
6110 main.log.error( self.name + ": " + self.handle.before )
6111 main.cleanAndExit()
6112 except Exception:
6113 main.log.exception( self.name + ": Uncaught exception!" )
6114 main.cleanAndExit()
6115
6116 def issuReset( self ):
6117 """
6118 Resets the In-Service Software Upgrade status after a rollback
6119
6120 Returns main.TRUE on success, main.ERROR on error, else main.FALSE
6121 """
6122 try:
6123 cmdStr = "issu reset"
6124 handle = self.sendline( cmdStr )
6125 assert handle is not None, "Error in sendline"
6126 assert "Command not found:" not in handle, handle
6127 assert "Unsupported command:" not in handle, handle
6128 # TODO: Check the version returned by this command
6129 if "Reset version" in handle:
6130 return main.TRUE
6131 else:
6132 return main.FALSE
6133 except AssertionError:
6134 main.log.exception( "" )
6135 return main.ERROR
6136 except TypeError:
6137 main.log.exception( self.name + ": Object not as expected" )
6138 return main.ERROR
6139 except pexpect.EOF:
6140 main.log.error( self.name + ": EOF exception found" )
6141 main.log.error( self.name + ": " + self.handle.before )
6142 main.cleanAndExit()
6143 except Exception:
6144 main.log.exception( self.name + ": Uncaught exception!" )
6145 main.cleanAndExit()
6146
6147 def issuStatus( self ):
6148 """
6149 Status of an In-Service Software Upgrade
6150
6151 Returns the output of the cli command or None on Error
6152 """
6153 try:
6154 cmdStr = "issu status"
6155 handle = self.sendline( cmdStr )
6156 assert handle is not None, "Error in sendline"
6157 assert "Command not found:" not in handle, handle
6158 assert "Unsupported command:" not in handle, handle
6159 return handle
6160 except AssertionError:
6161 main.log.exception( "" )
6162 return None
6163 except TypeError:
6164 main.log.exception( self.name + ": Object not as expected" )
6165 return None
6166 except pexpect.EOF:
6167 main.log.error( self.name + ": EOF exception found" )
6168 main.log.error( self.name + ": " + self.handle.before )
6169 main.cleanAndExit()
6170 except Exception:
6171 main.log.exception( self.name + ": Uncaught exception!" )
6172 main.cleanAndExit()
6173
6174 def issuVersion( self ):
6175 """
6176 Get the version of an In-Service Software Upgrade
6177
6178 Returns the output of the cli command or None on Error
6179 """
6180 try:
6181 cmdStr = "issu version"
6182 handle = self.sendline( cmdStr )
6183 assert handle is not None, "Error in sendline"
6184 assert "Command not found:" not in handle, handle
6185 assert "Unsupported command:" not in handle, handle
6186 return handle
6187 except AssertionError:
6188 main.log.exception( "" )
6189 return None
6190 except TypeError:
6191 main.log.exception( self.name + ": Object not as expected" )
6192 return None
6193 except pexpect.EOF:
6194 main.log.error( self.name + ": EOF exception found" )
6195 main.log.error( self.name + ": " + self.handle.before )
6196 main.cleanAndExit()
6197 except Exception:
6198 main.log.exception( self.name + ": Uncaught exception!" )
6199 main.cleanAndExit()
You Wange24d6272018-03-27 21:18:50 -07006200
6201 def mcastJoin( self, sIP, groupIP, sPort, dPorts ):
6202 """
6203 Create a multicast route by calling 'mcast-join' command
6204 sIP: source IP of the multicast route
6205 groupIP: group IP of the multicast route
6206 sPort: source port (e.g. of:0000000000000001/3 ) of the multicast route
6207 dPorts: a list of destination ports of the multicast route
6208 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6209 """
6210 try:
6211 cmdStr = "mcast-join"
6212 cmdStr += " " + str( sIP )
6213 cmdStr += " " + str( groupIP )
6214 cmdStr += " " + str( sPort )
6215 assert isinstance( dPorts, list )
6216 for dPort in dPorts:
6217 cmdStr += " " + str( dPort )
6218 handle = self.sendline( cmdStr )
6219 assert handle is not None, "Error in sendline"
6220 assert "Command not found:" not in handle, handle
6221 assert "Unsupported command:" not in handle, handle
6222 assert "Error executing command" not in handle, handle
6223 if "Added the mcast route" in handle:
6224 return main.TRUE
6225 else:
6226 return main.FALSE
6227 except AssertionError:
6228 main.log.exception( "" )
6229 return None
6230 except TypeError:
6231 main.log.exception( self.name + ": Object not as expected" )
6232 return None
6233 except pexpect.EOF:
6234 main.log.error( self.name + ": EOF exception found" )
6235 main.log.error( self.name + ": " + self.handle.before )
6236 main.cleanAndExit()
6237 except Exception:
6238 main.log.exception( self.name + ": Uncaught exception!" )
6239 main.cleanAndExit()
6240
6241 def mcastDelete( self, sIP, groupIP, dPorts ):
6242 """
6243 Delete a multicast route by calling 'mcast-delete' command
6244 sIP: source IP of the multicast route
6245 groupIP: group IP of the multicast route
6246 dPorts: a list of destination ports of the multicast route
6247 Returns main.TRUE if mcast route is deleted; Otherwise main.FALSE
6248 """
6249 try:
6250 cmdStr = "mcast-delete"
6251 cmdStr += " " + str( sIP )
6252 cmdStr += " " + str( groupIP )
6253 assert isinstance( dPorts, list )
6254 for dPort in dPorts:
6255 cmdStr += " " + str( dPort )
6256 handle = self.sendline( cmdStr )
6257 assert handle is not None, "Error in sendline"
6258 assert "Command not found:" not in handle, handle
6259 assert "Unsupported command:" not in handle, handle
6260 assert "Error executing command" not in handle, handle
6261 if "Updated the mcast route" in handle:
6262 return main.TRUE
6263 else:
6264 return main.FALSE
6265 except AssertionError:
6266 main.log.exception( "" )
6267 return None
6268 except TypeError:
6269 main.log.exception( self.name + ": Object not as expected" )
6270 return None
6271 except pexpect.EOF:
6272 main.log.error( self.name + ": EOF exception found" )
6273 main.log.error( self.name + ": " + self.handle.before )
6274 main.cleanAndExit()
6275 except Exception:
6276 main.log.exception( self.name + ": Uncaught exception!" )
6277 main.cleanAndExit()
6278
6279 def mcastHostJoin( self, sAddr, gAddr, srcs, sinks ):
6280 """
6281 Create a multicast route by calling 'mcast-host-join' command
6282 sAddr: we can provide * for ASM or a specific address for SSM
6283 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006284 srcs: a list of HostId of the sources e.g. ["00:AA:00:00:00:01/None"]
You Wange24d6272018-03-27 21:18:50 -07006285 sinks: a list of HostId of the sinks e.g. ["00:AA:00:00:01:05/40"]
6286 Returns main.TRUE if mcast route is added; Otherwise main.FALSE
6287 """
6288 try:
6289 cmdStr = "mcast-host-join"
6290 cmdStr += " -sAddr " + str( sAddr )
6291 cmdStr += " -gAddr " + str( gAddr )
6292 assert isinstance( srcs, list )
6293 for src in srcs:
6294 cmdStr += " -srcs " + str( src )
6295 assert isinstance( sinks, list )
6296 for sink in sinks:
6297 cmdStr += " -sinks " + str( sink )
6298 handle = self.sendline( cmdStr )
6299 assert handle is not None, "Error in sendline"
6300 assert "Command not found:" not in handle, handle
6301 assert "Unsupported command:" not in handle, handle
6302 assert "Error executing command" not in handle, handle
6303 if "Added the mcast route" in handle:
6304 return main.TRUE
6305 else:
6306 return main.FALSE
6307 except AssertionError:
6308 main.log.exception( "" )
6309 return None
6310 except TypeError:
6311 main.log.exception( self.name + ": Object not as expected" )
6312 return None
6313 except pexpect.EOF:
6314 main.log.error( self.name + ": EOF exception found" )
6315 main.log.error( self.name + ": " + self.handle.before )
6316 main.cleanAndExit()
6317 except Exception:
6318 main.log.exception( self.name + ": Uncaught exception!" )
6319 main.cleanAndExit()
6320
6321 def mcastHostDelete( self, sAddr, gAddr, host=None ):
6322 """
6323 Delete multicast sink(s) by calling 'mcast-host-delete' command
6324 sAddr: we can provide * for ASM or a specific address for SSM
6325 gAddr: specifies multicast group address
You Wangc02d8352018-04-17 16:42:10 -07006326 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
You Wange24d6272018-03-27 21:18:50 -07006327 will delete the route if not specified
6328 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6329 """
6330 try:
6331 cmdStr = "mcast-host-delete"
6332 cmdStr += " -sAddr " + str( sAddr )
6333 cmdStr += " -gAddr " + str( gAddr )
6334 if host:
6335 cmdStr += " -h " + str( host )
6336 handle = self.sendline( cmdStr )
6337 assert handle is not None, "Error in sendline"
6338 assert "Command not found:" not in handle, handle
6339 assert "Unsupported command:" not in handle, handle
6340 assert "Error executing command" not in handle, handle
6341 if "Updated the mcast route" in handle:
6342 return main.TRUE
6343 elif "Deleted the mcast route" in handle:
6344 return main.TRUE
6345 else:
6346 return main.FALSE
6347 except AssertionError:
6348 main.log.exception( "" )
6349 return None
6350 except TypeError:
6351 main.log.exception( self.name + ": Object not as expected" )
6352 return None
6353 except pexpect.EOF:
6354 main.log.error( self.name + ": EOF exception found" )
6355 main.log.error( self.name + ": " + self.handle.before )
6356 main.cleanAndExit()
6357 except Exception:
6358 main.log.exception( self.name + ": Uncaught exception!" )
6359 main.cleanAndExit()
6360
You Wang547893e2018-05-08 13:34:59 -07006361 def mcastSinkDelete( self, sAddr, gAddr, sink=None ):
6362 """
6363 Delete multicast sink(s) by calling 'mcast-sink-delete' command
6364 sAddr: we can provide * for ASM or a specific address for SSM
6365 gAddr: specifies multicast group address
6366 host: HostId of the sink e.g. "00:AA:00:00:01:05/40",
6367 will delete the route if not specified
6368 Returns main.TRUE if the mcast sink is deleted; Otherwise main.FALSE
6369 """
6370 try:
6371 cmdStr = "mcast-sink-delete"
6372 cmdStr += " -sAddr " + str( sAddr )
6373 cmdStr += " -gAddr " + str( gAddr )
6374 if sink:
6375 cmdStr += " -s " + str( sink )
6376 handle = self.sendline( cmdStr )
6377 assert handle is not None, "Error in sendline"
6378 assert "Command not found:" not in handle, handle
6379 assert "Unsupported command:" not in handle, handle
6380 assert "Error executing command" not in handle, handle
6381 if "Updated the mcast route" in handle:
6382 return main.TRUE
6383 elif "Deleted the mcast route" in handle:
6384 return main.TRUE
6385 else:
6386 return main.FALSE
6387 except AssertionError:
6388 main.log.exception( "" )
6389 return None
6390 except TypeError:
6391 main.log.exception( self.name + ": Object not as expected" )
6392 return None
6393 except pexpect.EOF:
6394 main.log.error( self.name + ": EOF exception found" )
6395 main.log.error( self.name + ": " + self.handle.before )
6396 main.cleanAndExit()
6397 except Exception:
6398 main.log.exception( self.name + ": Uncaught exception!" )
6399 main.cleanAndExit()
6400
You Wange24d6272018-03-27 21:18:50 -07006401 def mcastSourceDelete( self, sAddr, gAddr, srcs=None ):
6402 """
6403 Delete multicast src(s) by calling 'mcast-source-delete' command
6404 sAddr: we can provide * for ASM or a specific address for SSM
6405 gAddr: specifies multicast group address
You Wang547893e2018-05-08 13:34:59 -07006406 srcs: a list of host IDs of the sources e.g. ["00:AA:00:00:01:05/40"],
You Wange24d6272018-03-27 21:18:50 -07006407 will delete the route if not specified
6408 Returns main.TRUE if mcast sink is deleted; Otherwise main.FALSE
6409 """
6410 try:
6411 cmdStr = "mcast-source-delete"
6412 cmdStr += " -sAddr " + str( sAddr )
6413 cmdStr += " -gAddr " + str( gAddr )
6414 if srcs:
6415 assert isinstance( srcs, list )
6416 for src in srcs:
6417 cmdStr += " -src " + str( src )
6418 handle = self.sendline( cmdStr )
6419 assert handle is not None, "Error in sendline"
6420 assert "Command not found:" not in handle, handle
6421 assert "Unsupported command:" not in handle, handle
6422 assert "Error executing command" not in handle, handle
6423 if "Updated the mcast route" in handle:
6424 return main.TRUE
6425 elif "Deleted the mcast route" in handle:
6426 return main.TRUE
6427 else:
6428 return main.FALSE
6429 except AssertionError:
6430 main.log.exception( "" )
6431 return None
6432 except TypeError:
6433 main.log.exception( self.name + ": Object not as expected" )
6434 return None
6435 except pexpect.EOF:
6436 main.log.error( self.name + ": EOF exception found" )
6437 main.log.error( self.name + ": " + self.handle.before )
6438 main.cleanAndExit()
6439 except Exception:
6440 main.log.exception( self.name + ": Uncaught exception!" )
6441 main.cleanAndExit()
You Wang5da39c82018-04-26 22:55:08 -07006442
6443 def netcfg( self, jsonFormat=True, args="" ):
6444 """
6445 Run netcfg cli command with given args
6446 """
6447 try:
6448 cmdStr = "netcfg"
6449 if jsonFormat:
6450 cmdStr = cmdStr + " -j"
6451 if args:
6452 cmdStr = cmdStr + " " + str( args )
6453 handle = self.sendline( cmdStr )
6454 assert handle is not None, "Error in sendline"
6455 assert "Command not found:" not in handle, handle
6456 assert "Unsupported command:" not in handle, handle
6457 assert "Error executing command" not in handle, handle
6458 return handle
6459 except AssertionError:
6460 main.log.exception( "" )
6461 return None
6462 except TypeError:
6463 main.log.exception( self.name + ": Object not as expected" )
6464 return None
6465 except pexpect.EOF:
6466 main.log.error( self.name + ": EOF exception found" )
6467 main.log.error( self.name + ": " + self.handle.before )
6468 main.cleanAndExit()
6469 except Exception:
6470 main.log.exception( self.name + ": Uncaught exception!" )
6471 main.cleanAndExit()
6472
6473 def composeT3Command( self, sAddr, dAddr, ipv6=False, verbose=True ):
6474 """
6475 Compose and return t3-troubleshoot cli command for given source and destination addresses
6476 Options:
6477 sAddr: IP address of the source host
6478 dAddr: IP address of the destination host
6479 """
6480 try:
6481 # Collect information of both hosts from onos
6482 hosts = self.hosts()
6483 hosts = json.loads( hosts )
6484 sHost = None
6485 dHost = None
6486 for host in hosts:
6487 if sAddr in host[ "ipAddresses" ]:
6488 sHost = host
6489 elif dAddr in host[ "ipAddresses" ]:
6490 dHost = host
6491 if sHost and dHost:
6492 break
6493 assert sHost, "Not able to find host with IP {}".format( sAddr )
You Wang5da39c82018-04-26 22:55:08 -07006494 cmdStr = "t3-troubleshoot"
6495 if verbose:
6496 cmdStr += " -vv"
6497 cmdStr += " -s " + str( sAddr )
6498 # TODO: collect t3 for all locations of source host?
6499 cmdStr += " -sp " + str( sHost[ "locations" ][ 0 ][ "elementId" ] ) + "/" + str( sHost[ "locations" ][ 0 ][ "port" ] )
6500 cmdStr += " -sm " + str( sHost[ "mac" ] )
You Wangc9faf4c2018-05-02 12:05:50 -07006501 if sHost[ "vlan" ] != "None":
6502 cmdStr += " -vid " + sHost[ "vlan" ]
You Wang5da39c82018-04-26 22:55:08 -07006503 cmdStr += " -d " + str( dAddr )
6504 netcfg = self.netcfg( args="devices {}".format( sHost[ "locations" ][ 0 ][ "elementId" ] ) )
6505 netcfg = json.loads( netcfg )
6506 assert netcfg, "Failed to get netcfg"
6507 cmdStr += " -dm " + str( netcfg[ "segmentrouting" ][ "routerMac" ] )
6508 if ipv6:
6509 cmdStr += " -et ipv6"
6510 return cmdStr
6511 except AssertionError:
6512 main.log.exception( "" )
6513 return None
6514 except ( KeyError, TypeError ):
6515 main.log.exception( self.name + ": Object not as expected" )
6516 return None
6517 except Exception:
6518 main.log.exception( self.name + ": Uncaught exception!" )
6519 main.cleanAndExit()
6520
6521 def t3( self, sAddr, dAddr, ipv6=False ):
6522 """
6523 Run t3-troubleshoot cli command for given source and destination addresses
6524 Options:
6525 sAddr: IP address of the source host
6526 dAddr: IP address of the destination host
6527 """
6528 try:
6529 cmdStr = self.composeT3Command( sAddr, dAddr, ipv6 )
6530 handle = self.sendline( cmdStr )
6531 assert handle is not None, "Error in sendline"
6532 assert "Command not found:" not in handle, handle
6533 assert "Unsupported command:" not in handle, handle
6534 assert "Error executing command" not in handle, handle
6535 assert "Tracing packet" in handle
6536 return handle
6537 except AssertionError:
6538 main.log.exception( "" )
6539 return None
6540 except pexpect.EOF:
6541 main.log.error( self.name + ": EOF exception found" )
6542 main.log.error( self.name + ": " + self.handle.before )
6543 main.cleanAndExit()
6544 except Exception:
6545 main.log.exception( self.name + ": Uncaught exception!" )
6546 main.cleanAndExit()