blob: 218b1e8e4a744f542d2b17e47d23b4403744a487 [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:
283 # Wait for onos start ( -w ) and enter onos cli
284 startCliCommand = "onos -w "
285 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
365 # Wait for onos start ( -w ) and enter onos cli
366 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
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001154 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001155 """
andrewonlabe6745342014-10-17 14:29:13 -04001156 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001157 * hostIdOne: ONOS host id for host1
1158 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001159 Optional:
1160 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001161 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001162 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001163 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001164 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001165 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001166 Returns:
1167 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001168 """
andrewonlabe6745342014-10-17 14:29:13 -04001169 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001170 cmdStr = "add-host-intent "
1171 if vlanId:
1172 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001173 if setVlan:
1174 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001175 if encap:
1176 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001177 if bandwidth:
1178 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001179 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001180 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001181 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001182 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001183 if re.search( "Error", handle ):
1184 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001185 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001186 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001187 else:
1188 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001189 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001190 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001191 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001192 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001193 else:
1194 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001195 main.log.debug( "Response from ONOS was: " +
1196 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001197 return None
Jon Hallc6793552016-01-19 14:18:37 -08001198 except AssertionError:
1199 main.log.exception( "" )
1200 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001201 except TypeError:
1202 main.log.exception( self.name + ": Object not as expected" )
1203 return None
andrewonlabe6745342014-10-17 14:29:13 -04001204 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001205 main.log.error( self.name + ": EOF exception found" )
1206 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001207 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001208 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001209 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001210 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001211
kelvin-onlabd3b64892015-01-20 13:26:24 -08001212 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001213 """
andrewonlab7b31d232014-10-24 13:31:47 -04001214 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001215 * ingressDevice: device id of ingress device
1216 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001217 Optional:
1218 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001219 Description:
1220 Adds an optical intent by specifying an ingress and egress device
1221 Returns:
1222 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001223 """
andrewonlab7b31d232014-10-24 13:31:47 -04001224 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001225 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1226 " " + str( egressDevice )
1227 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001228 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001229 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001230 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001231 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001232 main.log.error( "Error in adding Optical intent" )
1233 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001234 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001235 main.log.info( "Optical intent installed between " +
1236 str( ingressDevice ) + " and " +
1237 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001238 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001239 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001240 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001241 else:
1242 main.log.error( "Error, intent ID not found" )
1243 return None
Jon Hallc6793552016-01-19 14:18:37 -08001244 except AssertionError:
1245 main.log.exception( "" )
1246 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001247 except TypeError:
1248 main.log.exception( self.name + ": Object not as expected" )
1249 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001250 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001251 main.log.error( self.name + ": EOF exception found" )
1252 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001253 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001254 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001255 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001256 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001257
kelvin-onlabd3b64892015-01-20 13:26:24 -08001258 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001259 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001260 ingressDevice,
1261 egressDevice,
1262 portIngress="",
1263 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001264 ethType="",
1265 ethSrc="",
1266 ethDst="",
1267 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001268 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001269 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001270 ipProto="",
1271 ipSrc="",
1272 ipDst="",
1273 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001274 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001275 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001276 setVlan="",
1277 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001278 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001279 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001280 * ingressDevice: device id of ingress device
1281 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001282 Optional:
1283 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001284 * ethSrc: specify ethSrc ( i.e. src mac addr )
1285 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001286 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001287 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001288 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001289 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001290 * ipSrc: specify ip source address
1291 * ipDst: specify ip destination address
1292 * tcpSrc: specify tcp source port
1293 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001294 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001295 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001296 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001297 Description:
kelvin8ec71442015-01-15 16:57:00 -08001298 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001299 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001300 Returns:
1301 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001302
Jon Halle3f39ff2015-01-13 11:50:53 -08001303 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001304 options developers provide for point-to-point
1305 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001306 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001307 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001308 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001309
Jeremy Songsterff553672016-05-12 17:06:23 -07001310 if ethType:
1311 cmd += " --ethType " + str( ethType )
1312 if ethSrc:
1313 cmd += " --ethSrc " + str( ethSrc )
1314 if ethDst:
1315 cmd += " --ethDst " + str( ethDst )
1316 if bandwidth:
1317 cmd += " --bandwidth " + str( bandwidth )
1318 if lambdaAlloc:
1319 cmd += " --lambda "
1320 if ipProto:
1321 cmd += " --ipProto " + str( ipProto )
1322 if ipSrc:
1323 cmd += " --ipSrc " + str( ipSrc )
1324 if ipDst:
1325 cmd += " --ipDst " + str( ipDst )
1326 if tcpSrc:
1327 cmd += " --tcpSrc " + str( tcpSrc )
1328 if tcpDst:
1329 cmd += " --tcpDst " + str( tcpDst )
1330 if vlanId:
1331 cmd += " -v " + str( vlanId )
1332 if setVlan:
1333 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001334 if encap:
1335 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001336 if protected:
1337 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001338
kelvin8ec71442015-01-15 16:57:00 -08001339 # Check whether the user appended the port
1340 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001341 if "/" in ingressDevice:
1342 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001343 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001344 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001345 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001346 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001347 # Would it make sense to throw an exception and exit
1348 # the test?
1349 return None
andrewonlab36af3822014-11-18 17:48:18 -05001350
kelvin8ec71442015-01-15 16:57:00 -08001351 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001352 str( ingressDevice ) + "/" +\
1353 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001354
kelvin-onlabd3b64892015-01-20 13:26:24 -08001355 if "/" in egressDevice:
1356 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001357 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001358 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001359 main.log.error( "You must specify the egress port" )
1360 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001361
kelvin8ec71442015-01-15 16:57:00 -08001362 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001363 str( egressDevice ) + "/" +\
1364 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001365
kelvin-onlab898a6c62015-01-16 14:13:53 -08001366 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001367 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001368 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001369 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001370 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001371 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001372 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001373 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001374 # TODO: print out all the options in this message?
1375 main.log.info( "Point-to-point intent installed between " +
1376 str( ingressDevice ) + " and " +
1377 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001378 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001379 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001380 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001381 else:
1382 main.log.error( "Error, intent ID not found" )
1383 return None
Jon Hallc6793552016-01-19 14:18:37 -08001384 except AssertionError:
1385 main.log.exception( "" )
1386 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001387 except TypeError:
1388 main.log.exception( self.name + ": Object not as expected" )
1389 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001390 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001391 main.log.error( self.name + ": EOF exception found" )
1392 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001393 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001394 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001395 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001396 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001397
kelvin-onlabd3b64892015-01-20 13:26:24 -08001398 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001399 self,
shahshreyac2f97072015-03-19 17:04:29 -07001400 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001401 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001402 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001403 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001404 ethType="",
1405 ethSrc="",
1406 ethDst="",
1407 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001408 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001409 ipProto="",
1410 ipSrc="",
1411 ipDst="",
1412 tcpSrc="",
1413 tcpDst="",
1414 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001415 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001416 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001417 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001418 partial=False,
1419 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001420 """
shahshreyad0c80432014-12-04 16:56:05 -08001421 Note:
shahshreya70622b12015-03-19 17:19:00 -07001422 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001423 is same. That is, all ingress devices include port numbers
1424 with a "/" or all ingress devices could specify device
1425 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001426 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001427 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001428 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001429 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001430 Optional:
1431 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001432 * ethSrc: specify ethSrc ( i.e. src mac addr )
1433 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001434 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001435 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001436 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001437 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001438 * ipSrc: specify ip source address
1439 * ipDst: specify ip destination address
1440 * tcpSrc: specify tcp source port
1441 * tcpDst: specify tcp destination port
1442 * setEthSrc: action to Rewrite Source MAC Address
1443 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001444 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001445 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001446 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001447 Description:
kelvin8ec71442015-01-15 16:57:00 -08001448 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001449 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001450 Returns:
1451 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001452
Jon Halle3f39ff2015-01-13 11:50:53 -08001453 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001454 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001455 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001456 """
shahshreyad0c80432014-12-04 16:56:05 -08001457 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001458 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001459
Jeremy Songsterff553672016-05-12 17:06:23 -07001460 if ethType:
1461 cmd += " --ethType " + str( ethType )
1462 if ethSrc:
1463 cmd += " --ethSrc " + str( ethSrc )
1464 if ethDst:
1465 cmd += " --ethDst " + str( ethDst )
1466 if bandwidth:
1467 cmd += " --bandwidth " + str( bandwidth )
1468 if lambdaAlloc:
1469 cmd += " --lambda "
1470 if ipProto:
1471 cmd += " --ipProto " + str( ipProto )
1472 if ipSrc:
1473 cmd += " --ipSrc " + str( ipSrc )
1474 if ipDst:
1475 cmd += " --ipDst " + str( ipDst )
1476 if tcpSrc:
1477 cmd += " --tcpSrc " + str( tcpSrc )
1478 if tcpDst:
1479 cmd += " --tcpDst " + str( tcpDst )
1480 if setEthSrc:
1481 cmd += " --setEthSrc " + str( setEthSrc )
1482 if setEthDst:
1483 cmd += " --setEthDst " + str( setEthDst )
1484 if vlanId:
1485 cmd += " -v " + str( vlanId )
1486 if setVlan:
1487 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001488 if partial:
1489 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001490 if encap:
1491 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001492
kelvin8ec71442015-01-15 16:57:00 -08001493 # Check whether the user appended the port
1494 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001495
1496 if portIngressList is None:
1497 for ingressDevice in ingressDeviceList:
1498 if "/" in ingressDevice:
1499 cmd += " " + str( ingressDevice )
1500 else:
1501 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001502 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001503 # TODO: perhaps more meaningful return
1504 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001505 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001506 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001507 for ingressDevice, portIngress in zip( ingressDeviceList,
1508 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001509 cmd += " " + \
1510 str( ingressDevice ) + "/" +\
1511 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001512 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001513 main.log.error( "Device list and port list does not " +
1514 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001515 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001516 if "/" in egressDevice:
1517 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001518 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001519 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001520 main.log.error( "You must specify " +
1521 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001522 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001523
kelvin8ec71442015-01-15 16:57:00 -08001524 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001525 str( egressDevice ) + "/" +\
1526 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001527 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001528 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001529 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001530 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001531 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001532 main.log.error( "Error in adding multipoint-to-singlepoint " +
1533 "intent" )
1534 return None
shahshreyad0c80432014-12-04 16:56:05 -08001535 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001536 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001537 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001538 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001539 else:
1540 main.log.error( "Error, intent ID not found" )
1541 return None
Jon Hallc6793552016-01-19 14:18:37 -08001542 except AssertionError:
1543 main.log.exception( "" )
1544 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001545 except TypeError:
1546 main.log.exception( self.name + ": Object not as expected" )
1547 return None
1548 except pexpect.EOF:
1549 main.log.error( self.name + ": EOF exception found" )
1550 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001551 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001552 except Exception:
1553 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001554 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001555
1556 def addSinglepointToMultipointIntent(
1557 self,
1558 ingressDevice,
1559 egressDeviceList,
1560 portIngress="",
1561 portEgressList=None,
1562 ethType="",
1563 ethSrc="",
1564 ethDst="",
1565 bandwidth="",
1566 lambdaAlloc=False,
1567 ipProto="",
1568 ipSrc="",
1569 ipDst="",
1570 tcpSrc="",
1571 tcpDst="",
1572 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001573 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001574 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001575 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001576 partial=False,
1577 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001578 """
1579 Note:
1580 This function assumes the format of all egress devices
1581 is same. That is, all egress devices include port numbers
1582 with a "/" or all egress devices could specify device
1583 ids and port numbers seperately.
1584 Required:
1585 * EgressDeviceList: List of device ids of egress device
1586 ( Atleast 2 eress devices required in the list )
1587 * ingressDevice: device id of ingress device
1588 Optional:
1589 * ethType: specify ethType
1590 * ethSrc: specify ethSrc ( i.e. src mac addr )
1591 * ethDst: specify ethDst ( i.e. dst mac addr )
1592 * bandwidth: specify bandwidth capacity of link
1593 * lambdaAlloc: if True, intent will allocate lambda
1594 for the specified intent
1595 * ipProto: specify ip protocol
1596 * ipSrc: specify ip source address
1597 * ipDst: specify ip destination address
1598 * tcpSrc: specify tcp source port
1599 * tcpDst: specify tcp destination port
1600 * setEthSrc: action to Rewrite Source MAC Address
1601 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001602 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001603 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001604 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001605 Description:
1606 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1607 specifying device id's and optional fields
1608 Returns:
1609 A string of the intent id or None on error
1610
1611 NOTE: This function may change depending on the
1612 options developers provide for singlepoint-to-multipoint
1613 intent via cli
1614 """
1615 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001616 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001617
Jeremy Songsterff553672016-05-12 17:06:23 -07001618 if ethType:
1619 cmd += " --ethType " + str( ethType )
1620 if ethSrc:
1621 cmd += " --ethSrc " + str( ethSrc )
1622 if ethDst:
1623 cmd += " --ethDst " + str( ethDst )
1624 if bandwidth:
1625 cmd += " --bandwidth " + str( bandwidth )
1626 if lambdaAlloc:
1627 cmd += " --lambda "
1628 if ipProto:
1629 cmd += " --ipProto " + str( ipProto )
1630 if ipSrc:
1631 cmd += " --ipSrc " + str( ipSrc )
1632 if ipDst:
1633 cmd += " --ipDst " + str( ipDst )
1634 if tcpSrc:
1635 cmd += " --tcpSrc " + str( tcpSrc )
1636 if tcpDst:
1637 cmd += " --tcpDst " + str( tcpDst )
1638 if setEthSrc:
1639 cmd += " --setEthSrc " + str( setEthSrc )
1640 if setEthDst:
1641 cmd += " --setEthDst " + str( setEthDst )
1642 if vlanId:
1643 cmd += " -v " + str( vlanId )
1644 if setVlan:
1645 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001646 if partial:
1647 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001648 if encap:
1649 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001650
1651 # Check whether the user appended the port
1652 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001653
kelvin-onlabb9408212015-04-01 13:34:04 -07001654 if "/" in ingressDevice:
1655 cmd += " " + str( ingressDevice )
1656 else:
1657 if not portIngress:
1658 main.log.error( "You must specify " +
1659 "the Ingress port" )
1660 return main.FALSE
1661
1662 cmd += " " +\
1663 str( ingressDevice ) + "/" +\
1664 str( portIngress )
1665
1666 if portEgressList is None:
1667 for egressDevice in egressDeviceList:
1668 if "/" in egressDevice:
1669 cmd += " " + str( egressDevice )
1670 else:
1671 main.log.error( "You must specify " +
1672 "the egress port" )
1673 # TODO: perhaps more meaningful return
1674 return main.FALSE
1675 else:
1676 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001677 for egressDevice, portEgress in zip( egressDeviceList,
1678 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001679 cmd += " " + \
1680 str( egressDevice ) + "/" +\
1681 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001682 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001683 main.log.error( "Device list and port list does not " +
1684 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001685 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001686 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001687 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001688 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001689 # If error, return error message
1690 if re.search( "Error", handle ):
1691 main.log.error( "Error in adding singlepoint-to-multipoint " +
1692 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001693 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001694 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001695 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001696 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001697 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001698 else:
1699 main.log.error( "Error, intent ID not found" )
1700 return None
Jon Hallc6793552016-01-19 14:18:37 -08001701 except AssertionError:
1702 main.log.exception( "" )
1703 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001704 except TypeError:
1705 main.log.exception( self.name + ": Object not as expected" )
1706 return None
shahshreyad0c80432014-12-04 16:56:05 -08001707 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001708 main.log.error( self.name + ": EOF exception found" )
1709 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001710 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001711 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001712 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001713 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001714
Hari Krishna9e232602015-04-13 17:29:08 -07001715 def addMplsIntent(
1716 self,
1717 ingressDevice,
1718 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001719 ingressPort="",
1720 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001721 ethType="",
1722 ethSrc="",
1723 ethDst="",
1724 bandwidth="",
1725 lambdaAlloc=False,
1726 ipProto="",
1727 ipSrc="",
1728 ipDst="",
1729 tcpSrc="",
1730 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001731 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001732 egressLabel="",
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001733 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001734 """
1735 Required:
1736 * ingressDevice: device id of ingress device
1737 * egressDevice: device id of egress device
1738 Optional:
1739 * ethType: specify ethType
1740 * ethSrc: specify ethSrc ( i.e. src mac addr )
1741 * ethDst: specify ethDst ( i.e. dst mac addr )
1742 * bandwidth: specify bandwidth capacity of link
1743 * lambdaAlloc: if True, intent will allocate lambda
1744 for the specified intent
1745 * ipProto: specify ip protocol
1746 * ipSrc: specify ip source address
1747 * ipDst: specify ip destination address
1748 * tcpSrc: specify tcp source port
1749 * tcpDst: specify tcp destination port
1750 * ingressLabel: Ingress MPLS label
1751 * egressLabel: Egress MPLS label
1752 Description:
1753 Adds MPLS intent by
1754 specifying device id's and optional fields
1755 Returns:
1756 A string of the intent id or None on error
1757
1758 NOTE: This function may change depending on the
1759 options developers provide for MPLS
1760 intent via cli
1761 """
1762 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001763 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001764
Jeremy Songsterff553672016-05-12 17:06:23 -07001765 if ethType:
1766 cmd += " --ethType " + str( ethType )
1767 if ethSrc:
1768 cmd += " --ethSrc " + str( ethSrc )
1769 if ethDst:
1770 cmd += " --ethDst " + str( ethDst )
1771 if bandwidth:
1772 cmd += " --bandwidth " + str( bandwidth )
1773 if lambdaAlloc:
1774 cmd += " --lambda "
1775 if ipProto:
1776 cmd += " --ipProto " + str( ipProto )
1777 if ipSrc:
1778 cmd += " --ipSrc " + str( ipSrc )
1779 if ipDst:
1780 cmd += " --ipDst " + str( ipDst )
1781 if tcpSrc:
1782 cmd += " --tcpSrc " + str( tcpSrc )
1783 if tcpDst:
1784 cmd += " --tcpDst " + str( tcpDst )
1785 if ingressLabel:
1786 cmd += " --ingressLabel " + str( ingressLabel )
1787 if egressLabel:
1788 cmd += " --egressLabel " + str( egressLabel )
1789 if priority:
1790 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001791
1792 # Check whether the user appended the port
1793 # or provided it as an input
1794 if "/" in ingressDevice:
1795 cmd += " " + str( ingressDevice )
1796 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001797 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001798 main.log.error( "You must specify the ingress port" )
1799 return None
1800
1801 cmd += " " + \
1802 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001803 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001804
1805 if "/" in egressDevice:
1806 cmd += " " + str( egressDevice )
1807 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001808 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001809 main.log.error( "You must specify the egress port" )
1810 return None
1811
1812 cmd += " " +\
1813 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001814 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001815
1816 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001817 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001818 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001819 # If error, return error message
1820 if re.search( "Error", handle ):
1821 main.log.error( "Error in adding mpls intent" )
1822 return None
1823 else:
1824 # TODO: print out all the options in this message?
1825 main.log.info( "MPLS intent installed between " +
1826 str( ingressDevice ) + " and " +
1827 str( egressDevice ) )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001828 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07001829 if match:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07001830 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07001831 else:
1832 main.log.error( "Error, intent ID not found" )
1833 return None
Jon Hallc6793552016-01-19 14:18:37 -08001834 except AssertionError:
1835 main.log.exception( "" )
1836 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001837 except TypeError:
1838 main.log.exception( self.name + ": Object not as expected" )
1839 return None
1840 except pexpect.EOF:
1841 main.log.error( self.name + ": EOF exception found" )
1842 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001843 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001844 except Exception:
1845 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001846 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001847
Jon Hallefbd9792015-03-05 16:11:36 -08001848 def removeIntent( self, intentId, app='org.onosproject.cli',
1849 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001850 """
shahshreya1c818fc2015-02-26 13:44:08 -08001851 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001852 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001853 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001854 -p or --purge: Purge the intent from the store after removal
1855
Jon Halle3f39ff2015-01-13 11:50:53 -08001856 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001857 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001858 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001859 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001860 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001861 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001862 if purge:
1863 cmdStr += " -p"
1864 if sync:
1865 cmdStr += " -s"
1866
1867 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001868 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001869 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001870 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001871 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001872 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001873 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001874 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001875 # TODO: Should this be main.TRUE
1876 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001877 except AssertionError:
1878 main.log.exception( "" )
1879 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001880 except TypeError:
1881 main.log.exception( self.name + ": Object not as expected" )
1882 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001883 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001884 main.log.error( self.name + ": EOF exception found" )
1885 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001886 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001887 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001888 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001889 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04001890
YPZhangfebf7302016-05-24 16:45:56 -07001891 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001892 """
1893 Description:
1894 Remove all the intents
1895 Optional args:-
1896 -s or --sync: Waits for the removal before returning
1897 -p or --purge: Purge the intent from the store after removal
1898 Returns:
1899 Returns main.TRUE if all intents are removed, otherwise returns
1900 main.FALSE; Returns None for exception
1901 """
1902 try:
1903 cmdStr = "remove-intent"
1904 if purge:
1905 cmdStr += " -p"
1906 if sync:
1907 cmdStr += " -s"
1908
1909 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001910 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001911 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08001912 assert "Command not found:" not in handle, handle
1913 if re.search( "Error", handle ):
1914 main.log.error( "Error in removing intent" )
1915 return main.FALSE
1916 else:
1917 return main.TRUE
1918 except AssertionError:
1919 main.log.exception( "" )
1920 return None
1921 except TypeError:
1922 main.log.exception( self.name + ": Object not as expected" )
1923 return None
1924 except pexpect.EOF:
1925 main.log.error( self.name + ": EOF exception found" )
1926 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001927 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001928 except Exception:
1929 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001930 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001931
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001932 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001933 """
1934 Purges all WITHDRAWN Intents
1935 """
1936 try:
1937 cmdStr = "purge-intents"
1938 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001939 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001940 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001941 if re.search( "Error", handle ):
1942 main.log.error( "Error in purging intents" )
1943 return main.FALSE
1944 else:
1945 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001946 except AssertionError:
1947 main.log.exception( "" )
1948 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001949 except TypeError:
1950 main.log.exception( self.name + ": Object not as expected" )
1951 return None
1952 except pexpect.EOF:
1953 main.log.error( self.name + ": EOF exception found" )
1954 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001955 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07001956 except Exception:
1957 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001958 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07001959
Devin Lime6fe3c42017-10-18 16:28:40 -07001960 def wipeout( self ):
1961 """
1962 Wipe out the flows,intents,links,devices,hosts, and groups from the ONOS.
1963 """
1964 try:
1965 cmdStr = "wipe-out please"
1966 handle = self.sendline( cmdStr, timeout=60 )
1967 assert handle is not None, "Error in sendline"
1968 assert "Command not found:" not in handle, handle
1969 return main.TRUE
1970 except AssertionError:
1971 main.log.exception( "" )
1972 return None
1973 except TypeError:
1974 main.log.exception( self.name + ": Object not as expected" )
1975 return None
1976 except pexpect.EOF:
1977 main.log.error( self.name + ": EOF exception found" )
1978 main.log.error( self.name + ": " + self.handle.before )
1979 main.cleanAndExit()
1980 except Exception:
1981 main.log.exception( self.name + ": Uncaught exception!" )
1982 main.cleanAndExit()
1983
kelvin-onlabd3b64892015-01-20 13:26:24 -08001984 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001985 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001986 NOTE: This method should be used after installing application:
1987 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001988 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001989 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001990 Description:
1991 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001992 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001993 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001994 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001995 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001996 cmdStr += " -j"
1997 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001998 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001999 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002000 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002001 except AssertionError:
2002 main.log.exception( "" )
2003 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002004 except TypeError:
2005 main.log.exception( self.name + ": Object not as expected" )
2006 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002007 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002008 main.log.error( self.name + ": EOF exception found" )
2009 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002010 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002011 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002012 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002013 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08002014
pingping-lin54b03372015-08-13 14:43:10 -07002015 def ipv4RouteNumber( self ):
2016 """
2017 NOTE: This method should be used after installing application:
2018 onos-app-sdnip
2019 Description:
2020 Obtain the total IPv4 routes number in the system
2021 """
2022 try:
Pratik Parab57963572017-05-09 11:37:54 -07002023 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002024 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002025 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002026 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002027 jsonResult = json.loads( handle )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002028 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002029 except AssertionError:
2030 main.log.exception( "" )
2031 return None
2032 except ( TypeError, ValueError ):
2033 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002034 return None
2035 except pexpect.EOF:
2036 main.log.error( self.name + ": EOF exception found" )
2037 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002038 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002039 except Exception:
2040 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002041 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002042
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002043 # =============Function to check Bandwidth allocation========
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002044 def allocations( self, jsonFormat = True, dollarSign = True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002045 """
2046 Description:
2047 Obtain Bandwidth Allocation Information from ONOS cli.
2048 """
2049 try:
2050 cmdStr = "allocations"
2051 if jsonFormat:
2052 cmdStr += " -j"
2053 handle = self.sendline( cmdStr, timeout=300, dollarSign=True )
2054 assert handle is not None, "Error in sendline"
2055 assert "Command not found:" not in handle, handle
2056 return handle
2057 except AssertionError:
2058 main.log.exception( "" )
2059 return None
2060 except ( TypeError, ValueError ):
2061 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2062 return None
2063 except pexpect.EOF:
2064 main.log.error( self.name + ": EOF exception found" )
2065 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002066 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002067 except Exception:
2068 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002069 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002070
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002071 def intents( self, jsonFormat = True, summary = False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002072 """
andrewonlabe6745342014-10-17 14:29:13 -04002073 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002074 Obtain intents from the ONOS cli.
2075 Optional:
2076 * jsonFormat: Enable output formatting in json, default to True
2077 * summary: Whether only output the intent summary, defaults to False
2078 * type: Only output a certain type of intent. This options is valid
2079 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002080 """
andrewonlabe6745342014-10-17 14:29:13 -04002081 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002082 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002083 if summary:
2084 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002085 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002086 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002087 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002088 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002089 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002090 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002091 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002092 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002093 else:
Jon Hallff566d52016-01-15 14:45:36 -08002094 intentType = ""
2095 # IF we want the summary of a specific intent type
2096 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002097 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002098 if intentType in jsonResult.keys():
2099 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002100 else:
Jon Hallff566d52016-01-15 14:45:36 -08002101 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002102 return handle
2103 else:
2104 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002105 except AssertionError:
2106 main.log.exception( "" )
2107 return None
2108 except ( TypeError, ValueError ):
2109 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002110 return None
2111 except pexpect.EOF:
2112 main.log.error( self.name + ": EOF exception found" )
2113 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002114 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002115 except Exception:
2116 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002117 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002118
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002119 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002120 """
You Wangfdcbfc42016-05-16 12:16:53 -07002121 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002122 Gets intent state. Accepts a single intent ID (string type) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002123 list of intent IDs.
2124 Parameters:
2125 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002126 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002127 Returns:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002128 Returns the state (string type) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002129 accepted.
2130 Returns a list of dictionaries if a list of intent IDs is accepted,
2131 and each dictionary maps 'id' to the Intent ID and 'state' to
2132 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002133 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002134
kelvin-onlab54400a92015-02-26 18:05:51 -08002135 try:
2136 state = "State is Undefined"
2137 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002138 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002139 else:
Jon Hallc6793552016-01-19 14:18:37 -08002140 rawJson = intentsJson
2141 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002142 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002143 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002144 if intentsId == intent[ 'id' ]:
2145 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002146 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002147 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002148 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002149 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002150 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002151 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002152 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002153 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002154 for intent in parsedIntentsJson:
2155 if intentsId[ i ] == intent[ 'id' ]:
2156 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002157 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002158 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002159 break
Jon Hallefbd9792015-03-05 16:11:36 -08002160 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002161 main.log.warn( "Could not find all intents in ONOS output" )
2162 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002163 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002164 else:
Jon Hall53158082017-05-18 11:17:00 -07002165 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002166 return None
Jon Hallc6793552016-01-19 14:18:37 -08002167 except ( TypeError, ValueError ):
2168 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002169 return None
2170 except pexpect.EOF:
2171 main.log.error( self.name + ": EOF exception found" )
2172 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002173 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002174 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002175 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002176 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002177
Jon Hallf539eb92017-05-22 17:18:42 -07002178 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002179 """
2180 Description:
2181 Check intents state
2182 Required:
2183 intentsId - List of intents ID to be checked
2184 Optional:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002185 expectedState - Check the expected state(s) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002186 state in the list.
2187 *NOTE: You can pass in a list of expected state,
2188 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002189 Return:
Jon Hall53158082017-05-18 11:17:00 -07002190 Returns main.TRUE only if all intent are the same as expected states,
2191 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002192 """
2193 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002194 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002195 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002196
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002197 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002198 intentsDict = []
2199 for intent in json.loads( self.intents() ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002200 if isinstance( intentsId, types.StringType ) \
2201 and intent.get( 'id' ) == intentsId:
2202 intentsDict.append( intent )
2203 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002204 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002205 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002206
2207 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002208 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002209 "getting intents state" )
2210 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002211
2212 if isinstance( expectedState, types.StringType ):
2213 for intents in intentsDict:
2214 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002215 main.log.debug( self.name + " : Intent ID - " +
2216 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002217 " actual state = " +
2218 intents.get( 'state' )
2219 + " does not equal expected state = "
2220 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002221 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002222 elif isinstance( expectedState, types.ListType ):
2223 for intents in intentsDict:
2224 if not any( state == intents.get( 'state' ) for state in
2225 expectedState ):
2226 main.log.debug( self.name + " : Intent ID - " +
2227 intents.get( 'id' ) +
2228 " actual state = " +
2229 intents.get( 'state' ) +
2230 " does not equal expected states = "
2231 + str( expectedState ) )
2232 returnValue = main.FALSE
2233
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002234 if returnValue == main.TRUE:
2235 main.log.info( self.name + ": All " +
2236 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002237 " intents are in " + str( expectedState ) +
2238 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002239 return returnValue
2240 except TypeError:
2241 main.log.exception( self.name + ": Object not as expected" )
2242 return None
2243 except pexpect.EOF:
2244 main.log.error( self.name + ": EOF exception found" )
2245 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002246 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002247 except Exception:
2248 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002249 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002250
Jon Hallf539eb92017-05-22 17:18:42 -07002251 def compareBandwidthAllocations( self, expectedAllocations ):
2252 """
2253 Description:
2254 Compare the allocated bandwidth with the given allocations
2255 Required:
2256 expectedAllocations - The expected ONOS output of the allocations command
2257 Return:
2258 Returns main.TRUE only if all intent are the same as expected states,
2259 otherwise returns main.FALSE.
2260 """
2261 # FIXME: Convert these string comparisons to object comparisons
2262 try:
2263 returnValue = main.TRUE
2264 bandwidthFailed = False
2265 rawAlloc = self.allocations()
2266 expectedFormat = StringIO( expectedAllocations )
2267 ONOSOutput = StringIO( rawAlloc )
2268 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2269 str( expectedFormat ) ) )
2270
2271 for actual, expected in izip( ONOSOutput, expectedFormat ):
2272 actual = actual.rstrip()
2273 expected = expected.rstrip()
2274 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2275 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002276 marker1 = actual.find( 'allocated' )
2277 m1 = actual[ :marker1 ]
2278 marker2 = expected.find( 'allocated' )
2279 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002280 if m1 != m2:
2281 bandwidthFailed = True
2282 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2283 bandwidthFailed = True
2284 expectedFormat.close()
2285 ONOSOutput.close()
2286
2287 if bandwidthFailed:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002288 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002289 returnValue = main.FALSE
2290 return returnValue
2291 except TypeError:
2292 main.log.exception( self.name + ": Object not as expected" )
2293 return None
2294 except pexpect.EOF:
2295 main.log.error( self.name + ": EOF exception found" )
2296 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002297 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002298 except Exception:
2299 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002300 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002301
You Wang66518af2016-05-16 15:32:59 -07002302 def compareIntent( self, intentDict ):
2303 """
2304 Description:
2305 Compare the intent ids and states provided in the argument with all intents in ONOS
2306 Return:
2307 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2308 Arguments:
2309 intentDict: a dictionary which maps intent ids to intent states
2310 """
2311 try:
2312 intentsRaw = self.intents()
2313 intentsJson = json.loads( intentsRaw )
2314 intentDictONOS = {}
2315 for intent in intentsJson:
2316 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002317 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002318 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002319 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002320 str( len( intentDict ) ) + " expected and " +
2321 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002322 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002323 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002324 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002325 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2326 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002327 else:
2328 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2329 main.log.debug( self.name + ": intent ID - " + intentID +
2330 " expected state is " + intentDict[ intentID ] +
2331 " but actual state is " + intentDictONOS[ intentID ] )
2332 returnValue = main.FALSE
2333 intentDictONOS.pop( intentID )
2334 if len( intentDictONOS ) > 0:
2335 returnValue = main.FALSE
2336 for intentID in intentDictONOS.keys():
2337 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002338 if returnValue == main.TRUE:
2339 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2340 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002341 except KeyError:
2342 main.log.exception( self.name + ": KeyError exception found" )
2343 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002344 except ( TypeError, ValueError ):
2345 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002346 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002347 except pexpect.EOF:
2348 main.log.error( self.name + ": EOF exception found" )
2349 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002350 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002351 except Exception:
2352 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002353 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002354
YPZhang14a4aa92016-07-15 13:37:15 -07002355 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002356 """
2357 Description:
2358 Check the number of installed intents.
2359 Optional:
2360 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002361 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002362 Return:
2363 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2364 , otherwise, returns main.FALSE.
2365 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002366
GlennRCed771242016-01-13 17:02:47 -08002367 try:
2368 cmd = "intents -s -j"
2369
2370 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002371 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002372 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002373 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002374 response = json.loads( response )
2375
2376 # get total and installed number, see if they are match
2377 allState = response.get( 'all' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002378 if allState.get( 'total' ) == allState.get( 'installed' ):
2379 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002380 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002381 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002382 return main.FALSE
2383
Jon Hallc6793552016-01-19 14:18:37 -08002384 except ( TypeError, ValueError ):
2385 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002386 return None
2387 except pexpect.EOF:
2388 main.log.error( self.name + ": EOF exception found" )
2389 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002390 if noExit:
2391 return main.FALSE
2392 else:
Devin Lim44075962017-08-11 10:56:37 -07002393 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002394 except pexpect.TIMEOUT:
2395 main.log.error( self.name + ": ONOS timeout" )
2396 return None
GlennRCed771242016-01-13 17:02:47 -08002397 except Exception:
2398 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002399 if noExit:
2400 return main.FALSE
2401 else:
Devin Lim44075962017-08-11 10:56:37 -07002402 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002403
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002404 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002405 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002406 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002407 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002408 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002409 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002410 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002411 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002412 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002413 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002414 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002415 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002416 if noCore:
2417 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002418 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002419 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002420 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002421 assert "Command not found:" not in handle, handle
2422 if re.search( "Error:", handle ):
2423 main.log.error( self.name + ": flows() response: " +
2424 str( handle ) )
2425 return handle
2426 except AssertionError:
2427 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002428 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002429 except TypeError:
2430 main.log.exception( self.name + ": Object not as expected" )
2431 return None
Jon Hallc6793552016-01-19 14:18:37 -08002432 except pexpect.TIMEOUT:
2433 main.log.error( self.name + ": ONOS timeout" )
2434 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002435 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002436 main.log.error( self.name + ": EOF exception found" )
2437 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002438 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002439 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002440 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002441 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002442
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002443 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002444 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002445 count = int( count ) if count else 0
2446 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002447
Jon Halle0f0b342017-04-18 11:43:47 -07002448 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002449 """
2450 Description:
GlennRCed771242016-01-13 17:02:47 -08002451 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002452 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2453 if the count of those states is 0, which means all current flows
2454 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002455 Optional:
GlennRCed771242016-01-13 17:02:47 -08002456 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002457 Return:
2458 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002459 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002460 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002461 """
2462 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002463 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002464 checkedStates = []
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002465 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002466 for s in states:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002467 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002468 if rawFlows:
2469 # if we didn't get flows or flows function return None, we should return
2470 # main.Flase
2471 checkedStates.append( json.loads( rawFlows ) )
2472 else:
2473 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002474 for i in range( len( states ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002475 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002476 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002477 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002478 except TypeError:
2479 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002480 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002481
GlennRCed771242016-01-13 17:02:47 -08002482 # We want to count PENDING_ADD if isPENDING is true
2483 if isPENDING:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002484 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002485 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002486 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002487 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002488 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002489 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002490 except ( TypeError, ValueError ):
2491 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002492 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002493
YPZhang240842b2016-05-17 12:00:50 -07002494 except AssertionError:
2495 main.log.exception( "" )
2496 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002497 except pexpect.TIMEOUT:
2498 main.log.error( self.name + ": ONOS timeout" )
2499 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002500 except pexpect.EOF:
2501 main.log.error( self.name + ": EOF exception found" )
2502 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002503 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002504 except Exception:
2505 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002506 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002507
GlennRCed771242016-01-13 17:02:47 -08002508 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002509 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002510 """
andrewonlab87852b02014-11-19 18:44:19 -05002511 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002512 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002513 a specific point-to-point intent definition
2514 Required:
GlennRCed771242016-01-13 17:02:47 -08002515 * ingress: specify source dpid
2516 * egress: specify destination dpid
2517 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002518 Optional:
GlennRCed771242016-01-13 17:02:47 -08002519 * offset: the keyOffset is where the next batch of intents
2520 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002521 * noExit: If set to True, TestON will not exit if any error when issus command
2522 * getResponse: If set to True, function will return ONOS response.
2523
GlennRCed771242016-01-13 17:02:47 -08002524 Returns: If failed to push test intents, it will returen None,
2525 if successful, return true.
2526 Timeout expection will return None,
2527 TypeError will return false
2528 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002529 """
andrewonlab87852b02014-11-19 18:44:19 -05002530 try:
GlennRCed771242016-01-13 17:02:47 -08002531 if background:
2532 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002533 else:
GlennRCed771242016-01-13 17:02:47 -08002534 back = ""
2535 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002536 ingress,
2537 egress,
2538 batchSize,
2539 offset,
2540 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002541 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002542 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002543 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002544 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002545 if getResponse:
2546 return response
2547
GlennRCed771242016-01-13 17:02:47 -08002548 # TODO: We should handle if there is failure in installation
2549 return main.TRUE
2550
Jon Hallc6793552016-01-19 14:18:37 -08002551 except AssertionError:
2552 main.log.exception( "" )
2553 return None
GlennRCed771242016-01-13 17:02:47 -08002554 except pexpect.TIMEOUT:
2555 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002556 return None
andrewonlab87852b02014-11-19 18:44:19 -05002557 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002558 main.log.error( self.name + ": EOF exception found" )
2559 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002560 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002561 except TypeError:
2562 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002563 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002564 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002565 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002566 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002567
YPZhangebf9eb52016-05-12 15:20:24 -07002568 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002569 """
2570 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002571 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002572 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002573 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002574 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002575 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002576
YPZhangb5d3f832016-01-23 22:54:26 -08002577 try:
YPZhange3109a72016-02-02 11:25:37 -08002578 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002579 cmd = "flows -c added"
2580 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2581 if rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002582 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002583 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002584 for l in rawFlows:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002585 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002586 else:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002587 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002588 return None
2589 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002590
You Wangd3cb2ce2016-05-16 14:01:24 -07002591 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002592 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002593 return None
2594 except pexpect.EOF:
2595 main.log.error( self.name + ": EOF exception found" )
2596 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002597 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002598 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002599 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002600 except pexpect.TIMEOUT:
2601 main.log.error( self.name + ": ONOS timeout" )
2602 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002603 except Exception:
2604 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002605 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002606 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002607 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002608
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00002609 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002610 """
2611 Description:
2612 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002613 Optional:
2614 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002615 Return:
2616 The number of intents
2617 """
2618 try:
2619 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002620 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002621 if response is None:
2622 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002623 response = json.loads( response )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002624 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002625 except ( TypeError, ValueError ):
2626 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002627 return None
2628 except pexpect.EOF:
2629 main.log.error( self.name + ": EOF exception found" )
2630 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002631 if noExit:
2632 return -1
2633 else:
Devin Lim44075962017-08-11 10:56:37 -07002634 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002635 except Exception:
2636 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002637 if noExit:
2638 return -1
2639 else:
Devin Lim44075962017-08-11 10:56:37 -07002640 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002641
kelvin-onlabd3b64892015-01-20 13:26:24 -08002642 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002643 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002644 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002645 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002646 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002647 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002648 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002649 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002650 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002651 cmdStr += " -j"
2652 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002653 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002654 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002655 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002656 except AssertionError:
2657 main.log.exception( "" )
2658 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002659 except TypeError:
2660 main.log.exception( self.name + ": Object not as expected" )
2661 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -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()
Jon Hallfebb1c72015-03-05 13:30:09 -08002666 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002667 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002668 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002669
kelvin-onlabd3b64892015-01-20 13:26:24 -08002670 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002671 """
2672 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002673 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002674 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002675 """
andrewonlab867212a2014-10-22 20:13:38 -04002676 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002677 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002678 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002679 cmdStr += " -j"
2680 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002681 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002682 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002683 if handle:
2684 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002685 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002686 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002687 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002688 else:
2689 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002690 except AssertionError:
2691 main.log.exception( "" )
2692 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002693 except TypeError:
2694 main.log.exception( self.name + ": Object not as expected" )
2695 return None
andrewonlab867212a2014-10-22 20:13:38 -04002696 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002697 main.log.error( self.name + ": EOF exception found" )
2698 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002699 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002700 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002701 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002702 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002703
kelvin8ec71442015-01-15 16:57:00 -08002704 # Wrapper functions ****************
2705 # Wrapper functions use existing driver
2706 # functions and extends their use case.
2707 # For example, we may use the output of
2708 # a normal driver function, and parse it
2709 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002710
kelvin-onlabd3b64892015-01-20 13:26:24 -08002711 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002712 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002713 Description:
2714 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002715 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002716 try:
kelvin8ec71442015-01-15 16:57:00 -08002717 # Obtain output of intents function
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002718 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002719 if intentsStr is None:
2720 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002721 # Convert to a dictionary
2722 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002723 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002724 for intent in intents:
2725 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002726 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002727 except TypeError:
2728 main.log.exception( self.name + ": Object not as expected" )
2729 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002730 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002731 main.log.error( self.name + ": EOF exception found" )
2732 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002733 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002734 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002735 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002736 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002737
You Wang3c276252016-09-21 15:21:36 -07002738 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002739 """
2740 Determine the number of flow rules for the given device id that are
2741 in the added state
You Wang3c276252016-09-21 15:21:36 -07002742 Params:
2743 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002744 """
2745 try:
You Wang3c276252016-09-21 15:21:36 -07002746 if core:
2747 cmdStr = "flows any " + str( deviceId ) + " | " +\
2748 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2749 else:
2750 cmdStr = "flows any " + str( deviceId ) + " | " +\
2751 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002752 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002753 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002754 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002755 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002756 except AssertionError:
2757 main.log.exception( "" )
2758 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002759 except pexpect.EOF:
2760 main.log.error( self.name + ": EOF exception found" )
2761 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002762 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002763 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002764 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002765 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002766
kelvin-onlabd3b64892015-01-20 13:26:24 -08002767 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002768 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002769 Use 'devices' function to obtain list of all devices
2770 and parse the result to obtain a list of all device
2771 id's. Returns this list. Returns empty list if no
2772 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002773 List is ordered sequentially
2774
andrewonlab3e15ead2014-10-15 14:21:34 -04002775 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002776 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002777 the ids. By obtaining the list of device ids on the fly,
2778 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002779 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002780 try:
kelvin8ec71442015-01-15 16:57:00 -08002781 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002782 devicesStr = self.devices( jsonFormat=False )
2783 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002784
kelvin-onlabd3b64892015-01-20 13:26:24 -08002785 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002786 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002787 return idList
kelvin8ec71442015-01-15 16:57:00 -08002788
2789 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002790 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002791 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002792 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002793 # Split list further into arguments before and after string
2794 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002795 # append to idList
2796 for arg in tempList:
2797 idList.append( arg.split( "id=" )[ 1 ] )
2798 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002799
Jon Halld4d4b372015-01-28 16:02:41 -08002800 except TypeError:
2801 main.log.exception( self.name + ": Object not as expected" )
2802 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002803 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002804 main.log.error( self.name + ": EOF exception found" )
2805 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002806 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002807 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002808 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002809 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002810
kelvin-onlabd3b64892015-01-20 13:26:24 -08002811 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002812 """
andrewonlab7c211572014-10-15 16:45:20 -04002813 Uses 'nodes' function to obtain list of all nodes
2814 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002815 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002816 Returns:
2817 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002818 """
andrewonlab7c211572014-10-15 16:45:20 -04002819 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002820 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002821 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002822 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002823 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002824 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002825 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002826 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002827 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002828 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002829 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002830 except ( TypeError, ValueError ):
2831 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002832 return None
andrewonlab7c211572014-10-15 16:45:20 -04002833 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002834 main.log.error( self.name + ": EOF exception found" )
2835 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002836 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002837 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002838 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002839 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002840
kelvin-onlabd3b64892015-01-20 13:26:24 -08002841 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002842 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002843 Return the first device from the devices api whose 'id' contains 'dpid'
2844 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002845 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002846 try:
kelvin8ec71442015-01-15 16:57:00 -08002847 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002848 return None
2849 else:
kelvin8ec71442015-01-15 16:57:00 -08002850 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002851 rawDevices = self.devices()
2852 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002853 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002854 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002855 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2856 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002857 return device
2858 return None
Jon Hallc6793552016-01-19 14:18:37 -08002859 except ( TypeError, ValueError ):
2860 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002861 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002862 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002863 main.log.error( self.name + ": EOF exception found" )
2864 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002865 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002866 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002867 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002868 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04002869
You Wang24139872016-05-03 11:48:47 -07002870 def getTopology( self, topologyOutput ):
2871 """
2872 Definition:
2873 Loads a json topology output
2874 Return:
2875 topology = current ONOS topology
2876 """
2877 import json
2878 try:
2879 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002880 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002881 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002882 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002883 except ( TypeError, ValueError ):
2884 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2885 return None
You Wang24139872016-05-03 11:48:47 -07002886 except pexpect.EOF:
2887 main.log.error( self.name + ": EOF exception found" )
2888 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002889 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07002890 except Exception:
2891 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002892 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07002893
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002894 def checkStatus( self, numoswitch, numolink, numoctrl = -1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002895 """
Jon Hallefbd9792015-03-05 16:11:36 -08002896 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002897 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002898 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002899
Flavio Castro82ee2f62016-06-07 15:04:12 -07002900 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002901 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002902 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002903 logLevel = level to log to.
2904 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002905
Jon Hallefbd9792015-03-05 16:11:36 -08002906 Returns: main.TRUE if the number of switches and links are correct,
2907 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002908 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002909 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002910 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002911 try:
You Wang13310252016-07-31 10:56:14 -07002912 summary = self.summary()
2913 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002914 except ( TypeError, ValueError ):
2915 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2916 return main.ERROR
2917 try:
2918 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07002919 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002920 return main.ERROR
2921 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002922 # Is the number of switches is what we expected
2923 devices = topology.get( 'devices', False )
2924 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002925 nodes = summary.get( 'nodes', False )
2926 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002927 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002928 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002929 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002930 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002931 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2932 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002933 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002934 output = output + "The number of links and switches match "\
2935 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002936 result = main.TRUE
2937 else:
You Wang24139872016-05-03 11:48:47 -07002938 output = output + \
2939 "The number of links and switches does not match " + \
2940 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002941 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002942 output = output + "\n ONOS sees %i devices" % int( devices )
2943 output = output + " (%i expected) " % int( numoswitch )
2944 output = output + "and %i links " % int( links )
2945 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002946 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002947 output = output + "and %i controllers " % int( nodes )
2948 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002949 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002950 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002951 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002952 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002953 else:
You Wang24139872016-05-03 11:48:47 -07002954 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002955 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002956 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002957 main.log.error( self.name + ": EOF exception found" )
2958 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002959 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002960 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002961 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002962 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002963
kelvin-onlabd3b64892015-01-20 13:26:24 -08002964 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002965 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002966 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002967 deviceId must be the id of a device as seen in the onos devices command
2968 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002969 role must be either master, standby, or none
2970
Jon Halle3f39ff2015-01-13 11:50:53 -08002971 Returns:
2972 main.TRUE or main.FALSE based on argument verification and
2973 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002974 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002975 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002976 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002977 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002978 cmdStr = "device-role " +\
2979 str( deviceId ) + " " +\
2980 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002981 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002982 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002983 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002984 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002985 if re.search( "Error", handle ):
2986 # end color output to escape any colours
2987 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002988 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002989 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002990 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002991 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002992 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002993 main.log.error( "Invalid 'role' given to device_role(). " +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07002994 "Value was '" + str( role ) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002995 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002996 except AssertionError:
2997 main.log.exception( "" )
2998 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002999 except TypeError:
3000 main.log.exception( self.name + ": Object not as expected" )
3001 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003002 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003003 main.log.error( self.name + ": EOF exception found" )
3004 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003005 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003006 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003007 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003008 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003009
kelvin-onlabd3b64892015-01-20 13:26:24 -08003010 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003011 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003012 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003013 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003014 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003015 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003016 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003017 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003018 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003019 cmdStr += " -j"
3020 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003021 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003022 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003023 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003024 except AssertionError:
3025 main.log.exception( "" )
3026 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003027 except TypeError:
3028 main.log.exception( self.name + ": Object not as expected" )
3029 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003030 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003031 main.log.error( self.name + ": EOF exception found" )
3032 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003033 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003034 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003035 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003036 main.cleanAndExit()
Jon Hall73cf9cc2014-11-20 22:28:38 -08003037
kelvin-onlabd3b64892015-01-20 13:26:24 -08003038 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003039 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003040 CLI command to get the current leader for the Election test application
3041 NOTE: Requires installation of the onos-app-election feature
3042 Returns: Node IP of the leader if one exists
3043 None if none exists
3044 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003045 """
Jon Hall94fd0472014-12-08 11:52:42 -08003046 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003047 cmdStr = "election-test-leader"
3048 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003049 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003050 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003051 # Leader
3052 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003053 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003054 nodeSearch = re.search( leaderPattern, response )
3055 if nodeSearch:
3056 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003057 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003058 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003059 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003060 # no leader
3061 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003062 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003063 nullSearch = re.search( nullPattern, response )
3064 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003065 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003066 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003067 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003068 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003069 main.log.error( "Error in electionTestLeader on " + self.name +
3070 ": " + "unexpected response" )
3071 main.log.error( repr( response ) )
3072 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003073 except AssertionError:
3074 main.log.exception( "" )
3075 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003076 except TypeError:
3077 main.log.exception( self.name + ": Object not as expected" )
3078 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003079 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003080 main.log.error( self.name + ": EOF exception found" )
3081 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003082 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003083 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003084 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003085 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003086
kelvin-onlabd3b64892015-01-20 13:26:24 -08003087 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003088 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003089 CLI command to run for leadership of the Election test application.
3090 NOTE: Requires installation of the onos-app-election feature
3091 Returns: Main.TRUE on success
3092 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003093 """
Jon Hall94fd0472014-12-08 11:52:42 -08003094 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003095 cmdStr = "election-test-run"
3096 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003097 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003098 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003099 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003100 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003101 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003102 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003103 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003104 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003105 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003106 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003107 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003108 main.log.error( "Error in electionTestRun on " + self.name +
3109 ": " + "unexpected response" )
3110 main.log.error( repr( response ) )
3111 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003112 except AssertionError:
3113 main.log.exception( "" )
3114 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003115 except TypeError:
3116 main.log.exception( self.name + ": Object not as expected" )
3117 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003118 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003119 main.log.error( self.name + ": EOF exception found" )
3120 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003121 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003122 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003123 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003124 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003125
kelvin-onlabd3b64892015-01-20 13:26:24 -08003126 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003127 """
Jon Hall94fd0472014-12-08 11:52:42 -08003128 * CLI command to withdraw the local node from leadership election for
3129 * the Election test application.
3130 #NOTE: Requires installation of the onos-app-election feature
3131 Returns: Main.TRUE on success
3132 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003133 """
Jon Hall94fd0472014-12-08 11:52:42 -08003134 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003135 cmdStr = "election-test-withdraw"
3136 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003137 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003138 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003139 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003140 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003141 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003142 if re.search( successPattern, response ):
3143 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003144 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003145 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003146 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003147 main.log.error( "Error in electionTestWithdraw on " +
3148 self.name + ": " + "unexpected response" )
3149 main.log.error( repr( response ) )
3150 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003151 except AssertionError:
3152 main.log.exception( "" )
3153 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003154 except TypeError:
3155 main.log.exception( self.name + ": Object not as expected" )
3156 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003157 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003158 main.log.error( self.name + ": EOF exception found" )
3159 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003160 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003161 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003162 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003163 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003164
kelvin8ec71442015-01-15 16:57:00 -08003165 def getDevicePortsEnabledCount( self, dpid ):
3166 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003167 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003168 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003169 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003170 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003171 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3172 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003173 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003174 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003175 if re.search( "No such device", output ):
3176 main.log.error( "Error in getting ports" )
3177 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003178 return output
Jon Hallc6793552016-01-19 14:18:37 -08003179 except AssertionError:
3180 main.log.exception( "" )
3181 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003182 except TypeError:
3183 main.log.exception( self.name + ": Object not as expected" )
3184 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003185 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003186 main.log.error( self.name + ": EOF exception found" )
3187 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003188 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003189 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003190 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003191 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003192
kelvin8ec71442015-01-15 16:57:00 -08003193 def getDeviceLinksActiveCount( self, dpid ):
3194 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003195 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003196 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003197 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003198 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003199 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3200 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003201 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003202 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003203 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003204 main.log.error( "Error in getting ports " )
3205 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003206 return output
Jon Hallc6793552016-01-19 14:18:37 -08003207 except AssertionError:
3208 main.log.exception( "" )
3209 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003210 except TypeError:
3211 main.log.exception( self.name + ": Object not as expected" )
3212 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003213 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003214 main.log.error( self.name + ": EOF exception found" )
3215 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003216 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003217 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003218 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003219 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003220
kelvin8ec71442015-01-15 16:57:00 -08003221 def getAllIntentIds( self ):
3222 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003223 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003224 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003225 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003226 cmdStr = "onos:intents | grep id="
3227 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003228 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003229 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003230 if re.search( "Error", output ):
3231 main.log.error( "Error in getting ports" )
3232 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003233 return output
Jon Hallc6793552016-01-19 14:18:37 -08003234 except AssertionError:
3235 main.log.exception( "" )
3236 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003237 except TypeError:
3238 main.log.exception( self.name + ": Object not as expected" )
3239 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003240 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003241 main.log.error( self.name + ": EOF exception found" )
3242 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003243 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003244 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003245 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003246 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003247
Jon Hall73509952015-02-24 16:42:56 -08003248 def intentSummary( self ):
3249 """
Jon Hallefbd9792015-03-05 16:11:36 -08003250 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003251 """
3252 try:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003253 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003254 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003255 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003256 states.append( intent.get( 'state', None ) )
3257 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003258 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003259 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003260 except ( TypeError, ValueError ):
3261 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003262 return None
3263 except pexpect.EOF:
3264 main.log.error( self.name + ": EOF exception found" )
3265 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003266 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003267 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003268 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003269 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003270
Jon Hall61282e32015-03-19 11:34:11 -07003271 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003272 """
3273 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003274 Optional argument:
3275 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003276 """
Jon Hall63604932015-02-26 17:09:50 -08003277 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003278 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003279 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003280 cmdStr += " -j"
3281 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003282 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003283 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003284 return output
Jon Hallc6793552016-01-19 14:18:37 -08003285 except AssertionError:
3286 main.log.exception( "" )
3287 return None
Jon Hall63604932015-02-26 17:09:50 -08003288 except TypeError:
3289 main.log.exception( self.name + ": Object not as expected" )
3290 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003291 except pexpect.EOF:
3292 main.log.error( self.name + ": EOF exception found" )
3293 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003294 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003295 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003296 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003297 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003298
acsmarsa4a4d1e2015-07-10 16:01:24 -07003299 def leaderCandidates( self, jsonFormat=True ):
3300 """
3301 Returns the output of the leaders -c command.
3302 Optional argument:
3303 * jsonFormat - boolean indicating if you want output in json
3304 """
3305 try:
3306 cmdStr = "onos:leaders -c"
3307 if jsonFormat:
3308 cmdStr += " -j"
3309 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003310 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003311 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003312 return output
Jon Hallc6793552016-01-19 14:18:37 -08003313 except AssertionError:
3314 main.log.exception( "" )
3315 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003316 except TypeError:
3317 main.log.exception( self.name + ": Object not as expected" )
3318 return None
3319 except pexpect.EOF:
3320 main.log.error( self.name + ": EOF exception found" )
3321 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003322 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003323 except Exception:
3324 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003325 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003326
Jon Hallc6793552016-01-19 14:18:37 -08003327 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003328 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003329 Returns a list in format [leader,candidate1,candidate2,...] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003330 topic parameter and an empty list if the topic doesn't exist
3331 If no leader is elected leader in the returned list will be "none"
3332 Returns None if there is a type error processing the json object
3333 """
3334 try:
Jon Hall6e709752016-02-01 13:38:46 -08003335 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003336 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003337 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003338 assert "Command not found:" not in rawOutput, rawOutput
3339 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003340 results = []
3341 for dict in output:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003342 if dict[ "topic" ] == topic:
3343 leader = dict[ "leader" ]
3344 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003345 results.append( leader )
3346 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003347 return results
Jon Hallc6793552016-01-19 14:18:37 -08003348 except AssertionError:
3349 main.log.exception( "" )
3350 return None
3351 except ( TypeError, ValueError ):
3352 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003353 return None
3354 except pexpect.EOF:
3355 main.log.error( self.name + ": EOF exception found" )
3356 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003357 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003358 except Exception:
3359 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003360 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003361
Jon Hall61282e32015-03-19 11:34:11 -07003362 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003363 """
3364 Returns the output of the intent Pending map.
3365 """
Jon Hall63604932015-02-26 17:09:50 -08003366 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003367 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003368 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003369 cmdStr += " -j"
3370 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003371 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003372 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003373 return output
Jon Hallc6793552016-01-19 14:18:37 -08003374 except AssertionError:
3375 main.log.exception( "" )
3376 return None
Jon Hall63604932015-02-26 17:09:50 -08003377 except TypeError:
3378 main.log.exception( self.name + ": Object not as expected" )
3379 return None
3380 except pexpect.EOF:
3381 main.log.error( self.name + ": EOF exception found" )
3382 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003383 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003384 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003385 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003386 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003387
Jon Hall2c8959e2016-12-16 12:17:34 -08003388 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003389 """
3390 Returns the output of the raft partitions command for ONOS.
3391 """
Jon Hall61282e32015-03-19 11:34:11 -07003392 # Sample JSON
3393 # {
3394 # "leader": "tcp://10.128.30.11:7238",
3395 # "members": [
3396 # "tcp://10.128.30.11:7238",
3397 # "tcp://10.128.30.17:7238",
3398 # "tcp://10.128.30.13:7238",
3399 # ],
3400 # "name": "p1",
3401 # "term": 3
3402 # },
Jon Hall63604932015-02-26 17:09:50 -08003403 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003404 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003405 if candidates:
3406 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003407 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003408 cmdStr += " -j"
3409 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003410 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003411 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003412 return output
Jon Hallc6793552016-01-19 14:18:37 -08003413 except AssertionError:
3414 main.log.exception( "" )
3415 return None
Jon Hall63604932015-02-26 17:09:50 -08003416 except TypeError:
3417 main.log.exception( self.name + ": Object not as expected" )
3418 return None
3419 except pexpect.EOF:
3420 main.log.error( self.name + ": EOF exception found" )
3421 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003422 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003423 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003424 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003425 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003426
Jon Halle9f909e2016-09-23 10:43:12 -07003427 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003428 """
3429 Returns the output of the apps command for ONOS. This command lists
3430 information about installed ONOS applications
3431 """
3432 # Sample JSON object
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003433 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003434 # "description":"ONOS OpenFlow protocol southbound providers",
3435 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003436 # "features":"[onos-openflow]","state":"ACTIVE"}]
Jon Hallbe379602015-03-24 13:39:32 -07003437 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003438 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003439 if summary:
3440 cmdStr += " -s"
3441 if active:
3442 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003443 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003444 cmdStr += " -j"
3445 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003446 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003447 assert "Command not found:" not in output, output
3448 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003449 return output
Jon Hallbe379602015-03-24 13:39:32 -07003450 # FIXME: look at specific exceptions/Errors
3451 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003452 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003453 return None
3454 except TypeError:
3455 main.log.exception( self.name + ": Object not as expected" )
3456 return None
3457 except pexpect.EOF:
3458 main.log.error( self.name + ": EOF exception found" )
3459 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003460 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003461 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003462 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003463 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003464
Jon Hall146f1522015-03-24 15:33:24 -07003465 def appStatus( self, appName ):
3466 """
3467 Uses the onos:apps cli command to return the status of an application.
3468 Returns:
3469 "ACTIVE" - If app is installed and activated
3470 "INSTALLED" - If app is installed and deactivated
3471 "UNINSTALLED" - If app is not installed
3472 None - on error
3473 """
Jon Hall146f1522015-03-24 15:33:24 -07003474 try:
3475 if not isinstance( appName, types.StringType ):
3476 main.log.error( self.name + ".appStatus(): appName must be" +
3477 " a string" )
3478 return None
3479 output = self.apps( jsonFormat=True )
3480 appsJson = json.loads( output )
3481 state = None
3482 for app in appsJson:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003483 if appName == app.get( 'name' ):
3484 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003485 break
3486 if state == "ACTIVE" or state == "INSTALLED":
3487 return state
3488 elif state is None:
Jon Hall8bafdc02017-09-05 11:36:26 -07003489 main.log.warn( "{} app not found", appName )
Jon Hall146f1522015-03-24 15:33:24 -07003490 return "UNINSTALLED"
3491 elif state:
3492 main.log.error( "Unexpected state from 'onos:apps': " +
3493 str( state ) )
3494 return state
Jon Hallc6793552016-01-19 14:18:37 -08003495 except ( TypeError, ValueError ):
3496 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003497 return None
3498 except pexpect.EOF:
3499 main.log.error( self.name + ": EOF exception found" )
3500 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003501 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003502 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003503 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003504 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003505
Jon Hallbe379602015-03-24 13:39:32 -07003506 def app( self, appName, option ):
3507 """
3508 Interacts with the app command for ONOS. This command manages
3509 application inventory.
3510 """
Jon Hallbe379602015-03-24 13:39:32 -07003511 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003512 # Validate argument types
3513 valid = True
3514 if not isinstance( appName, types.StringType ):
3515 main.log.error( self.name + ".app(): appName must be a " +
3516 "string" )
3517 valid = False
3518 if not isinstance( option, types.StringType ):
3519 main.log.error( self.name + ".app(): option must be a string" )
3520 valid = False
3521 if not valid:
3522 return main.FALSE
3523 # Validate Option
3524 option = option.lower()
3525 # NOTE: Install may become a valid option
3526 if option == "activate":
3527 pass
3528 elif option == "deactivate":
3529 pass
3530 elif option == "uninstall":
3531 pass
3532 else:
3533 # Invalid option
3534 main.log.error( "The ONOS app command argument only takes " +
3535 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003536 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003537 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003538 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003539 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003540 assert output is not None, "Error in sendline"
3541 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003542 if "Error executing command" in output:
3543 main.log.error( "Error in processing onos:app command: " +
3544 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003545 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003546 elif "No such application" in output:
3547 main.log.error( "The application '" + appName +
3548 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003549 return main.FALSE
3550 elif "Command not found:" in output:
3551 main.log.error( "Error in processing onos:app command: " +
3552 str( output ) )
3553 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003554 elif "Unsupported command:" in output:
3555 main.log.error( "Incorrect command given to 'app': " +
3556 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003557 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003558 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003559 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003560 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003561 except AssertionError:
3562 main.log.exception( self.name + ": AssertionError exception found" )
3563 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003564 except TypeError:
3565 main.log.exception( self.name + ": Object not as expected" )
3566 return main.ERROR
3567 except pexpect.EOF:
3568 main.log.error( self.name + ": EOF exception found" )
3569 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003570 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003571 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003572 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003573 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003574
Jon Hallbd16b922015-03-26 17:53:15 -07003575 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003576 """
3577 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003578 appName is the hierarchical app name, not the feature name
3579 If check is True, method will check the status of the app after the
3580 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003581 Returns main.TRUE if the command was successfully sent
3582 main.FALSE if the cli responded with an error or given
3583 incorrect input
3584 """
3585 try:
3586 if not isinstance( appName, types.StringType ):
3587 main.log.error( self.name + ".activateApp(): appName must be" +
3588 " a string" )
3589 return main.FALSE
3590 status = self.appStatus( appName )
3591 if status == "INSTALLED":
3592 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003593 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003594 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003595 status = self.appStatus( appName )
3596 if status == "ACTIVE":
3597 return main.TRUE
3598 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003599 main.log.debug( "The state of application " +
3600 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003601 time.sleep( 1 )
3602 return main.FALSE
3603 else: # not 'check' or command didn't succeed
3604 return response
Jon Hall146f1522015-03-24 15:33:24 -07003605 elif status == "ACTIVE":
3606 return main.TRUE
3607 elif status == "UNINSTALLED":
3608 main.log.error( self.name + ": Tried to activate the " +
3609 "application '" + appName + "' which is not " +
3610 "installed." )
3611 else:
3612 main.log.error( "Unexpected return value from appStatus: " +
3613 str( status ) )
3614 return main.ERROR
3615 except TypeError:
3616 main.log.exception( self.name + ": Object not as expected" )
3617 return main.ERROR
3618 except pexpect.EOF:
3619 main.log.error( self.name + ": EOF exception found" )
3620 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003621 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003622 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003623 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003624 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003625
Jon Hallbd16b922015-03-26 17:53:15 -07003626 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003627 """
3628 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003629 appName is the hierarchical app name, not the feature name
3630 If check is True, method will check the status of the app after the
3631 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003632 Returns main.TRUE if the command was successfully sent
3633 main.FALSE if the cli responded with an error or given
3634 incorrect input
3635 """
3636 try:
3637 if not isinstance( appName, types.StringType ):
3638 main.log.error( self.name + ".deactivateApp(): appName must " +
3639 "be a string" )
3640 return main.FALSE
3641 status = self.appStatus( appName )
3642 if status == "INSTALLED":
3643 return main.TRUE
3644 elif status == "ACTIVE":
3645 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003646 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003647 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003648 status = self.appStatus( appName )
3649 if status == "INSTALLED":
3650 return main.TRUE
3651 else:
3652 time.sleep( 1 )
3653 return main.FALSE
3654 else: # not check or command didn't succeed
3655 return response
Jon Hall146f1522015-03-24 15:33:24 -07003656 elif status == "UNINSTALLED":
3657 main.log.warn( self.name + ": Tried to deactivate the " +
3658 "application '" + appName + "' which is not " +
3659 "installed." )
3660 return main.TRUE
3661 else:
3662 main.log.error( "Unexpected return value from appStatus: " +
3663 str( status ) )
3664 return main.ERROR
3665 except TypeError:
3666 main.log.exception( self.name + ": Object not as expected" )
3667 return main.ERROR
3668 except pexpect.EOF:
3669 main.log.error( self.name + ": EOF exception found" )
3670 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003671 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003672 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003673 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003674 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003675
Jon Hallbd16b922015-03-26 17:53:15 -07003676 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003677 """
3678 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003679 appName is the hierarchical app name, not the feature name
3680 If check is True, method will check the status of the app after the
3681 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003682 Returns main.TRUE if the command was successfully sent
3683 main.FALSE if the cli responded with an error or given
3684 incorrect input
3685 """
3686 # TODO: check with Thomas about the state machine for apps
3687 try:
3688 if not isinstance( appName, types.StringType ):
3689 main.log.error( self.name + ".uninstallApp(): appName must " +
3690 "be a string" )
3691 return main.FALSE
3692 status = self.appStatus( appName )
3693 if status == "INSTALLED":
3694 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003695 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003696 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003697 status = self.appStatus( appName )
3698 if status == "UNINSTALLED":
3699 return main.TRUE
3700 else:
3701 time.sleep( 1 )
3702 return main.FALSE
3703 else: # not check or command didn't succeed
3704 return response
Jon Hall146f1522015-03-24 15:33:24 -07003705 elif status == "ACTIVE":
3706 main.log.warn( self.name + ": Tried to uninstall the " +
3707 "application '" + appName + "' which is " +
3708 "currently active." )
3709 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003710 if check and response == main.TRUE:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003711 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003712 status = self.appStatus( appName )
3713 if status == "UNINSTALLED":
3714 return main.TRUE
3715 else:
3716 time.sleep( 1 )
3717 return main.FALSE
3718 else: # not check or command didn't succeed
3719 return response
Jon Hall146f1522015-03-24 15:33:24 -07003720 elif status == "UNINSTALLED":
3721 return main.TRUE
3722 else:
3723 main.log.error( "Unexpected return value from appStatus: " +
3724 str( status ) )
3725 return main.ERROR
3726 except TypeError:
3727 main.log.exception( self.name + ": Object not as expected" )
3728 return main.ERROR
3729 except pexpect.EOF:
3730 main.log.error( self.name + ": EOF exception found" )
3731 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003732 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003733 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003734 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003735 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003736
3737 def appIDs( self, jsonFormat=True ):
3738 """
3739 Show the mappings between app id and app names given by the 'app-ids'
3740 cli command
3741 """
3742 try:
3743 cmdStr = "app-ids"
3744 if jsonFormat:
3745 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003746 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003747 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003748 assert "Command not found:" not in output, output
3749 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003750 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003751 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003752 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003753 return None
3754 except TypeError:
3755 main.log.exception( self.name + ": Object not as expected" )
3756 return None
3757 except pexpect.EOF:
3758 main.log.error( self.name + ": EOF exception found" )
3759 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003760 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003761 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003762 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003763 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003764
3765 def appToIDCheck( self ):
3766 """
3767 This method will check that each application's ID listed in 'apps' is
3768 the same as the ID listed in 'app-ids'. The check will also check that
3769 there are no duplicate IDs issued. Note that an app ID should be
3770 a globaly unique numerical identifier for app/app-like features. Once
3771 an ID is registered, the ID is never freed up so that if an app is
3772 reinstalled it will have the same ID.
3773
3774 Returns: main.TRUE if the check passes and
3775 main.FALSE if the check fails or
3776 main.ERROR if there is some error in processing the test
3777 """
3778 try:
Jon Hall390696c2015-05-05 17:13:41 -07003779 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003780 rawJson = self.appIDs( jsonFormat=True )
3781 if rawJson:
3782 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003783 else:
Jon Hallc6793552016-01-19 14:18:37 -08003784 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003785 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003786 rawJson = self.apps( jsonFormat=True )
3787 if rawJson:
3788 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003789 else:
Jon Hallc6793552016-01-19 14:18:37 -08003790 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003791 bail = True
3792 if bail:
3793 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003794 result = main.TRUE
3795 for app in apps:
3796 appID = app.get( 'id' )
3797 if appID is None:
3798 main.log.error( "Error parsing app: " + str( app ) )
3799 result = main.FALSE
3800 appName = app.get( 'name' )
3801 if appName is None:
3802 main.log.error( "Error parsing app: " + str( app ) )
3803 result = main.FALSE
3804 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003805 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003806 # main.log.debug( "Comparing " + str( app ) + " to " +
3807 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003808 if not current: # if ids doesn't have this id
3809 result = main.FALSE
3810 main.log.error( "'app-ids' does not have the ID for " +
3811 str( appName ) + " that apps does." )
3812 elif len( current ) > 1:
3813 # there is more than one app with this ID
3814 result = main.FALSE
3815 # We will log this later in the method
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003816 elif not current[ 0 ][ 'name' ] == appName:
3817 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07003818 result = main.FALSE
3819 main.log.error( "'app-ids' has " + str( currentName ) +
3820 " registered under id:" + str( appID ) +
3821 " but 'apps' has " + str( appName ) )
3822 else:
3823 pass # id and name match!
3824 # now make sure that app-ids has no duplicates
3825 idsList = []
3826 namesList = []
3827 for item in ids:
3828 idsList.append( item[ 'id' ] )
3829 namesList.append( item[ 'name' ] )
3830 if len( idsList ) != len( set( idsList ) ) or\
3831 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07003832 main.log.error( "'app-ids' has some duplicate entries: \n"
3833 + json.dumps( ids,
3834 sort_keys=True,
3835 indent=4,
3836 separators=( ',', ': ' ) ) )
3837 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003838 return result
Jon Hallc6793552016-01-19 14:18:37 -08003839 except ( TypeError, ValueError ):
3840 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003841 return main.ERROR
3842 except pexpect.EOF:
3843 main.log.error( self.name + ": EOF exception found" )
3844 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003845 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003846 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003847 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003848 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003849
Jon Hallfb760a02015-04-13 15:35:03 -07003850 def getCfg( self, component=None, propName=None, short=False,
3851 jsonFormat=True ):
3852 """
3853 Get configuration settings from onos cli
3854 Optional arguments:
3855 component - Optionally only list configurations for a specific
3856 component. If None, all components with configurations
3857 are displayed. Case Sensitive string.
3858 propName - If component is specified, propName option will show
3859 only this specific configuration from that component.
3860 Case Sensitive string.
3861 jsonFormat - Returns output as json. Note that this will override
3862 the short option
3863 short - Short, less verbose, version of configurations.
3864 This is overridden by the json option
3865 returns:
3866 Output from cli as a string or None on error
3867 """
3868 try:
3869 baseStr = "cfg"
3870 cmdStr = " get"
3871 componentStr = ""
3872 if component:
3873 componentStr += " " + component
3874 if propName:
3875 componentStr += " " + propName
3876 if jsonFormat:
3877 baseStr += " -j"
3878 elif short:
3879 baseStr += " -s"
3880 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003881 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003882 assert "Command not found:" not in output, output
3883 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003884 return output
3885 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003886 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003887 return None
3888 except TypeError:
3889 main.log.exception( self.name + ": Object not as expected" )
3890 return None
3891 except pexpect.EOF:
3892 main.log.error( self.name + ": EOF exception found" )
3893 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003894 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003895 except Exception:
3896 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003897 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003898
3899 def setCfg( self, component, propName, value=None, check=True ):
3900 """
3901 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003902 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003903 component - The case sensitive name of the component whose
3904 property is to be set
3905 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003906 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003907 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00003908 property and revert it to it's default value(if applicable)
Jon Hallfb760a02015-04-13 15:35:03 -07003909 check - Boolean, Check whether the option was successfully set this
3910 only applies when a value is given.
3911 returns:
3912 main.TRUE on success or main.FALSE on failure. If check is False,
3913 will return main.TRUE unless there is an error
3914 """
3915 try:
3916 baseStr = "cfg"
3917 cmdStr = " set " + str( component ) + " " + str( propName )
3918 if value is not None:
3919 cmdStr += " " + str( value )
3920 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003921 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003922 assert "Command not found:" not in output, output
3923 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003924 if value and check:
3925 results = self.getCfg( component=str( component ),
3926 propName=str( propName ),
3927 jsonFormat=True )
3928 # Check if current value is what we just set
3929 try:
3930 jsonOutput = json.loads( results )
3931 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003932 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003933 main.log.exception( "Error parsing cfg output" )
3934 main.log.error( "output:" + repr( results ) )
3935 return main.FALSE
3936 if current == str( value ):
3937 return main.TRUE
3938 return main.FALSE
3939 return main.TRUE
3940 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003941 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003942 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003943 except ( TypeError, ValueError ):
3944 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003945 return main.FALSE
3946 except pexpect.EOF:
3947 main.log.error( self.name + ": EOF exception found" )
3948 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003949 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003950 except Exception:
3951 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003952 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003953
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003954 def distPrimitivesSend( self, cmd ):
3955 """
3956 Function to handle sending cli commands for the distributed primitives test app
3957
3958 This command will catch some exceptions and retry the command on some
3959 specific store exceptions.
3960
3961 Required arguments:
3962 cmd - The command to send to the cli
3963 returns:
3964 string containing the cli output
3965 None on Error
3966 """
3967 try:
3968 output = self.sendline( cmd )
3969 try:
3970 assert output is not None, "Error in sendline"
3971 # TODO: Maybe make this less hardcoded
3972 # ConsistentMap Exceptions
3973 assert "org.onosproject.store.service" not in output
3974 # Node not leader
3975 assert "java.lang.IllegalStateException" not in output
3976 except AssertionError:
3977 main.log.error( "Error in processing '" + cmd + "' " +
3978 "command: " + str( output ) )
3979 retryTime = 30 # Conservative time, given by Madan
3980 main.log.info( "Waiting " + str( retryTime ) +
3981 "seconds before retrying." )
3982 time.sleep( retryTime ) # Due to change in mastership
3983 output = self.sendline( cmd )
3984 assert output is not None, "Error in sendline"
3985 assert "Command not found:" not in output, output
3986 assert "Error executing command" not in output, output
3987 main.log.info( self.name + ": " + output )
3988 return output
3989 except AssertionError:
3990 main.log.exception( "Error in processing '" + cmd + "' command." )
3991 return None
3992 except TypeError:
3993 main.log.exception( self.name + ": Object not as expected" )
3994 return None
3995 except pexpect.EOF:
3996 main.log.error( self.name + ": EOF exception found" )
3997 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003998 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003999 except Exception:
4000 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004001 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004002
Jon Hall390696c2015-05-05 17:13:41 -07004003 def setTestAdd( self, setName, values ):
4004 """
4005 CLI command to add elements to a distributed set.
4006 Arguments:
4007 setName - The name of the set to add to.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004008 values - The value(s) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004009 Example usages:
4010 setTestAdd( "set1", "a b c" )
4011 setTestAdd( "set2", "1" )
4012 returns:
4013 main.TRUE on success OR
4014 main.FALSE if elements were already in the set OR
4015 main.ERROR on error
4016 """
4017 try:
4018 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004019 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004020 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4021 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004022 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004023 return main.TRUE
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004024 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07004025 return main.FALSE
4026 else:
4027 main.log.error( self.name + ": setTestAdd did not" +
4028 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004029 main.log.debug( self.name + " actual: " + repr( output ) )
4030 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004031 except TypeError:
4032 main.log.exception( self.name + ": Object not as expected" )
4033 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004034 except Exception:
4035 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004036 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004037
4038 def setTestRemove( self, setName, values, clear=False, retain=False ):
4039 """
4040 CLI command to remove elements from a distributed set.
4041 Required arguments:
4042 setName - The name of the set to remove from.
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004043 values - The value(s) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004044 Optional arguments:
4045 clear - Clear all elements from the set
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004046 retain - Retain only the given values. (intersection of the
4047 original set and the given set)
Jon Hall390696c2015-05-05 17:13:41 -07004048 returns:
4049 main.TRUE on success OR
4050 main.FALSE if the set was not changed OR
4051 main.ERROR on error
4052 """
4053 try:
4054 cmdStr = "set-test-remove "
4055 if clear:
4056 cmdStr += "-c " + str( setName )
4057 elif retain:
4058 cmdStr += "-r " + str( setName ) + " " + str( values )
4059 else:
4060 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004061 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004062 if clear:
4063 pattern = "Set " + str( setName ) + " cleared"
4064 if re.search( pattern, output ):
4065 return main.TRUE
4066 elif retain:
4067 positivePattern = str( setName ) + " was pruned to contain " +\
4068 "only elements of set \[(.*)\]"
4069 negativePattern = str( setName ) + " was not changed by " +\
4070 "retaining only elements of the set " +\
4071 "\[(.*)\]"
4072 if re.search( positivePattern, output ):
4073 return main.TRUE
4074 elif re.search( negativePattern, output ):
4075 return main.FALSE
4076 else:
4077 positivePattern = "\[(.*)\] was removed from the set " +\
4078 str( setName )
4079 if ( len( values.split() ) == 1 ):
4080 negativePattern = "\[(.*)\] was not in set " +\
4081 str( setName )
4082 else:
4083 negativePattern = "No element of \[(.*)\] was in set " +\
4084 str( setName )
4085 if re.search( positivePattern, output ):
4086 return main.TRUE
4087 elif re.search( negativePattern, output ):
4088 return main.FALSE
4089 main.log.error( self.name + ": setTestRemove did not" +
4090 " match expected output" )
4091 main.log.debug( self.name + " expected: " + pattern )
4092 main.log.debug( self.name + " actual: " + repr( output ) )
4093 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004094 except TypeError:
4095 main.log.exception( self.name + ": Object not as expected" )
4096 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004097 except Exception:
4098 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004099 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004100
4101 def setTestGet( self, setName, values="" ):
4102 """
4103 CLI command to get the elements in a distributed set.
4104 Required arguments:
4105 setName - The name of the set to remove from.
4106 Optional arguments:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004107 values - The value(s) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004108 returns:
4109 main.ERROR on error OR
4110 A list of elements in the set if no optional arguments are
4111 supplied OR
4112 A tuple containing the list then:
4113 main.FALSE if the given values are not in the set OR
4114 main.TRUE if the given values are in the set OR
4115 """
4116 try:
4117 values = str( values ).strip()
4118 setName = str( setName ).strip()
4119 length = len( values.split() )
4120 containsCheck = None
4121 # Patterns to match
4122 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004123 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004124 containsTrue = "Set " + setName + " contains the value " + values
4125 containsFalse = "Set " + setName + " did not contain the value " +\
4126 values
4127 containsAllTrue = "Set " + setName + " contains the the subset " +\
4128 setPattern
4129 containsAllFalse = "Set " + setName + " did not contain the the" +\
4130 " subset " + setPattern
4131
4132 cmdStr = "set-test-get "
4133 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004134 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004135 if length == 0:
4136 match = re.search( pattern, output )
4137 else: # if given values
4138 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004139 patternTrue = pattern + "\r\n" + containsTrue
4140 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004141 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004142 patternTrue = pattern + "\r\n" + containsAllTrue
4143 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004144 matchTrue = re.search( patternTrue, output )
4145 matchFalse = re.search( patternFalse, output )
4146 if matchTrue:
4147 containsCheck = main.TRUE
4148 match = matchTrue
4149 elif matchFalse:
4150 containsCheck = main.FALSE
4151 match = matchFalse
4152 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004153 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004154 "expected output" )
4155 main.log.debug( self.name + " expected: " + pattern )
4156 main.log.debug( self.name + " actual: " + repr( output ) )
4157 match = None
4158 if match:
4159 setMatch = match.group( 1 )
4160 if setMatch == '':
4161 setList = []
4162 else:
4163 setList = setMatch.split( ", " )
4164 if length > 0:
4165 return ( setList, containsCheck )
4166 else:
4167 return setList
4168 else: # no match
4169 main.log.error( self.name + ": setTestGet did not" +
4170 " match expected output" )
4171 main.log.debug( self.name + " expected: " + pattern )
4172 main.log.debug( self.name + " actual: " + repr( output ) )
4173 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004174 except TypeError:
4175 main.log.exception( self.name + ": Object not as expected" )
4176 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004177 except Exception:
4178 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004179 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004180
4181 def setTestSize( self, setName ):
4182 """
4183 CLI command to get the elements in a distributed set.
4184 Required arguments:
4185 setName - The name of the set to remove from.
4186 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004187 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004188 None on error
4189 """
4190 try:
4191 # TODO: Should this check against the number of elements returned
4192 # and then return true/false based on that?
4193 setName = str( setName ).strip()
4194 # Patterns to match
4195 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004196 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004197 setPattern
4198 cmdStr = "set-test-get -s "
4199 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004200 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004201 match = re.search( pattern, output )
4202 if match:
4203 setSize = int( match.group( 1 ) )
4204 setMatch = match.group( 2 )
4205 if len( setMatch.split() ) == setSize:
4206 main.log.info( "The size returned by " + self.name +
4207 " matches the number of elements in " +
4208 "the returned set" )
4209 else:
4210 main.log.error( "The size returned by " + self.name +
4211 " does not match the number of " +
4212 "elements in the returned set." )
4213 return setSize
4214 else: # no match
4215 main.log.error( self.name + ": setTestGet did not" +
4216 " match expected output" )
4217 main.log.debug( self.name + " expected: " + pattern )
4218 main.log.debug( self.name + " actual: " + repr( output ) )
4219 return None
Jon Hall390696c2015-05-05 17:13:41 -07004220 except TypeError:
4221 main.log.exception( self.name + ": Object not as expected" )
4222 return None
Jon Hall390696c2015-05-05 17:13:41 -07004223 except Exception:
4224 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004225 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004226
Jon Hall80daded2015-05-27 16:07:00 -07004227 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004228 """
4229 Command to list the various counters in the system.
4230 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004231 if jsonFormat, a string of the json object returned by the cli
4232 command
4233 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004234 None on error
4235 """
Jon Hall390696c2015-05-05 17:13:41 -07004236 try:
Jon Hall390696c2015-05-05 17:13:41 -07004237 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004238 if jsonFormat:
4239 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004240 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004241 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004242 assert "Command not found:" not in output, output
4243 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004244 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004245 return output
Jon Hall390696c2015-05-05 17:13:41 -07004246 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004247 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004248 return None
Jon Hall390696c2015-05-05 17:13:41 -07004249 except TypeError:
4250 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004251 return None
Jon Hall390696c2015-05-05 17:13:41 -07004252 except pexpect.EOF:
4253 main.log.error( self.name + ": EOF exception found" )
4254 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004255 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004256 except Exception:
4257 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004258 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004259
Jon Hall935db192016-04-19 00:22:04 -07004260 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004261 """
Jon Halle1a3b752015-07-22 13:02:46 -07004262 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004263 Required arguments:
4264 counter - The name of the counter to increment.
4265 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004266 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004267 returns:
4268 integer value of the counter or
4269 None on Error
4270 """
4271 try:
4272 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004273 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004274 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004275 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004276 if delta != 1:
4277 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004278 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004279 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004280 match = re.search( pattern, output )
4281 if match:
4282 return int( match.group( 1 ) )
4283 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004284 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004285 " match expected output." )
4286 main.log.debug( self.name + " expected: " + pattern )
4287 main.log.debug( self.name + " actual: " + repr( output ) )
4288 return None
Jon Hall390696c2015-05-05 17:13:41 -07004289 except TypeError:
4290 main.log.exception( self.name + ": Object not as expected" )
4291 return None
Jon Hall390696c2015-05-05 17:13:41 -07004292 except Exception:
4293 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004294 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004295
Jon Hall935db192016-04-19 00:22:04 -07004296 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004297 """
4298 CLI command to get a distributed counter then add a delta to it.
4299 Required arguments:
4300 counter - The name of the counter to increment.
4301 Optional arguments:
4302 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004303 returns:
4304 integer value of the counter or
4305 None on Error
4306 """
4307 try:
4308 counter = str( counter )
4309 delta = int( delta )
4310 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004311 cmdStr += counter
4312 if delta != 1:
4313 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004314 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004315 pattern = counter + " was updated to (-?\d+)"
4316 match = re.search( pattern, output )
4317 if match:
4318 return int( match.group( 1 ) )
4319 else:
4320 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4321 " match expected output." )
4322 main.log.debug( self.name + " expected: " + pattern )
4323 main.log.debug( self.name + " actual: " + repr( output ) )
4324 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004325 except TypeError:
4326 main.log.exception( self.name + ": Object not as expected" )
4327 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004328 except Exception:
4329 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004330 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004331
4332 def valueTestGet( self, valueName ):
4333 """
4334 CLI command to get the value of an atomic value.
4335 Required arguments:
4336 valueName - The name of the value to get.
4337 returns:
4338 string value of the value or
4339 None on Error
4340 """
4341 try:
4342 valueName = str( valueName )
4343 cmdStr = "value-test "
4344 operation = "get"
4345 cmdStr = "value-test {} {}".format( valueName,
4346 operation )
4347 output = self.distPrimitivesSend( cmdStr )
4348 pattern = "(\w+)"
4349 match = re.search( pattern, output )
4350 if match:
4351 return match.group( 1 )
4352 else:
4353 main.log.error( self.name + ": valueTestGet did not" +
4354 " match expected output." )
4355 main.log.debug( self.name + " expected: " + pattern )
4356 main.log.debug( self.name + " actual: " + repr( output ) )
4357 return None
4358 except TypeError:
4359 main.log.exception( self.name + ": Object not as expected" )
4360 return None
4361 except Exception:
4362 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004363 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004364
4365 def valueTestSet( self, valueName, newValue ):
4366 """
4367 CLI command to set the value of an atomic value.
4368 Required arguments:
4369 valueName - The name of the value to set.
4370 newValue - The value to assign to the given value.
4371 returns:
4372 main.TRUE on success or
4373 main.ERROR on Error
4374 """
4375 try:
4376 valueName = str( valueName )
4377 newValue = str( newValue )
4378 operation = "set"
4379 cmdStr = "value-test {} {} {}".format( valueName,
4380 operation,
4381 newValue )
4382 output = self.distPrimitivesSend( cmdStr )
4383 if output is not None:
4384 return main.TRUE
4385 else:
4386 return main.ERROR
4387 except TypeError:
4388 main.log.exception( self.name + ": Object not as expected" )
4389 return main.ERROR
4390 except Exception:
4391 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004392 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004393
4394 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4395 """
4396 CLI command to compareAndSet the value of an atomic value.
4397 Required arguments:
4398 valueName - The name of the value.
4399 oldValue - Compare the current value of the atomic value to this
4400 newValue - If the value equals oldValue, set the value to newValue
4401 returns:
4402 main.TRUE on success or
4403 main.FALSE on failure or
4404 main.ERROR on Error
4405 """
4406 try:
4407 valueName = str( valueName )
4408 oldValue = str( oldValue )
4409 newValue = str( newValue )
4410 operation = "compareAndSet"
4411 cmdStr = "value-test {} {} {} {}".format( valueName,
4412 operation,
4413 oldValue,
4414 newValue )
4415 output = self.distPrimitivesSend( cmdStr )
4416 pattern = "(\w+)"
4417 match = re.search( pattern, output )
4418 if match:
4419 result = match.group( 1 )
4420 if result == "true":
4421 return main.TRUE
4422 elif result == "false":
4423 return main.FALSE
4424 else:
4425 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4426 " match expected output." )
4427 main.log.debug( self.name + " expected: " + pattern )
4428 main.log.debug( self.name + " actual: " + repr( output ) )
4429 return main.ERROR
4430 except TypeError:
4431 main.log.exception( self.name + ": Object not as expected" )
4432 return main.ERROR
4433 except Exception:
4434 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004435 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004436
4437 def valueTestGetAndSet( self, valueName, newValue ):
4438 """
4439 CLI command to getAndSet the value of an atomic value.
4440 Required arguments:
4441 valueName - The name of the value to get.
4442 newValue - The value to assign to the given value
4443 returns:
4444 string value of the value or
4445 None on Error
4446 """
4447 try:
4448 valueName = str( valueName )
4449 cmdStr = "value-test "
4450 operation = "getAndSet"
4451 cmdStr += valueName + " " + operation
4452 cmdStr = "value-test {} {} {}".format( valueName,
4453 operation,
4454 newValue )
4455 output = self.distPrimitivesSend( cmdStr )
4456 pattern = "(\w+)"
4457 match = re.search( pattern, output )
4458 if match:
4459 return match.group( 1 )
4460 else:
4461 main.log.error( self.name + ": valueTestGetAndSet did not" +
4462 " match expected output." )
4463 main.log.debug( self.name + " expected: " + pattern )
4464 main.log.debug( self.name + " actual: " + repr( output ) )
4465 return None
4466 except TypeError:
4467 main.log.exception( self.name + ": Object not as expected" )
4468 return None
4469 except Exception:
4470 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004471 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004472
4473 def valueTestDestroy( self, valueName ):
4474 """
4475 CLI command to destroy an atomic value.
4476 Required arguments:
4477 valueName - The name of the value to destroy.
4478 returns:
4479 main.TRUE on success or
4480 main.ERROR on Error
4481 """
4482 try:
4483 valueName = str( valueName )
4484 cmdStr = "value-test "
4485 operation = "destroy"
4486 cmdStr += valueName + " " + operation
4487 output = self.distPrimitivesSend( cmdStr )
4488 if output is not None:
4489 return main.TRUE
4490 else:
4491 return main.ERROR
4492 except TypeError:
4493 main.log.exception( self.name + ": Object not as expected" )
4494 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004495 except Exception:
4496 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004497 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004498
YPZhangfebf7302016-05-24 16:45:56 -07004499 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004500 """
4501 Description: Execute summary command in onos
4502 Returns: json object ( summary -j ), returns main.FALSE if there is
4503 no output
4504
4505 """
4506 try:
4507 cmdStr = "summary"
4508 if jsonFormat:
4509 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004510 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004511 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004512 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004513 assert "Error:" not in handle, handle
Devin Lima7cfdbd2017-09-29 15:02:22 -07004514 assert "Error executing" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004515 if not handle:
4516 main.log.error( self.name + ": There is no output in " +
4517 "summary command" )
4518 return main.FALSE
4519 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004520 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004521 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004522 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004523 except TypeError:
4524 main.log.exception( self.name + ": Object not as expected" )
4525 return None
4526 except pexpect.EOF:
4527 main.log.error( self.name + ": EOF exception found" )
4528 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004529 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004530 except Exception:
4531 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004532 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004533
Jon Hall935db192016-04-19 00:22:04 -07004534 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004535 """
4536 CLI command to get the value of a key in a consistent map using
4537 transactions. This a test function and can only get keys from the
4538 test map hard coded into the cli command
4539 Required arguments:
4540 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004541 returns:
4542 The string value of the key or
4543 None on Error
4544 """
4545 try:
4546 keyName = str( keyName )
4547 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004548 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004549 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004550 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4551 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004552 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004553 return None
4554 else:
4555 match = re.search( pattern, output )
4556 if match:
4557 return match.groupdict()[ 'value' ]
4558 else:
4559 main.log.error( self.name + ": transactionlMapGet did not" +
4560 " match expected output." )
4561 main.log.debug( self.name + " expected: " + pattern )
4562 main.log.debug( self.name + " actual: " + repr( output ) )
4563 return None
4564 except TypeError:
4565 main.log.exception( self.name + ": Object not as expected" )
4566 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004567 except Exception:
4568 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004569 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004570
Jon Hall935db192016-04-19 00:22:04 -07004571 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004572 """
4573 CLI command to put a value into 'numKeys' number of keys in a
4574 consistent map using transactions. This a test function and can only
4575 put into keys named 'Key#' of the test map hard coded into the cli command
4576 Required arguments:
4577 numKeys - Number of keys to add the value to
4578 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004579 returns:
4580 A dictionary whose keys are the name of the keys put into the map
4581 and the values of the keys are dictionaries whose key-values are
4582 'value': value put into map and optionaly
4583 'oldValue': Previous value in the key or
4584 None on Error
4585
4586 Example output
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004587 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4588 'Key2': {'value': 'Testing'} }
Jon Hall2a5002c2015-08-21 16:49:11 -07004589 """
4590 try:
4591 numKeys = str( numKeys )
4592 value = str( value )
4593 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004594 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004595 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004596 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4597 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4598 results = {}
4599 for line in output.splitlines():
4600 new = re.search( newPattern, line )
4601 updated = re.search( updatedPattern, line )
4602 if new:
4603 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4604 elif updated:
4605 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004606 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004607 else:
4608 main.log.error( self.name + ": transactionlMapGet did not" +
4609 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004610 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4611 newPattern,
4612 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004613 main.log.debug( self.name + " actual: " + repr( output ) )
4614 return results
4615 except TypeError:
4616 main.log.exception( self.name + ": Object not as expected" )
4617 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004618 except Exception:
4619 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004620 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004621
acsmarsdaea66c2015-09-03 11:44:06 -07004622 def maps( self, jsonFormat=True ):
4623 """
4624 Description: Returns result of onos:maps
4625 Optional:
4626 * jsonFormat: enable json formatting of output
4627 """
4628 try:
4629 cmdStr = "maps"
4630 if jsonFormat:
4631 cmdStr += " -j"
4632 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004633 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004634 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004635 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004636 except AssertionError:
4637 main.log.exception( "" )
4638 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004639 except TypeError:
4640 main.log.exception( self.name + ": Object not as expected" )
4641 return None
4642 except pexpect.EOF:
4643 main.log.error( self.name + ": EOF exception found" )
4644 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004645 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004646 except Exception:
4647 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004648 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004649
4650 def getSwController( self, uri, jsonFormat=True ):
4651 """
4652 Descrition: Gets the controller information from the device
4653 """
4654 try:
4655 cmd = "device-controllers "
4656 if jsonFormat:
4657 cmd += "-j "
4658 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004659 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004660 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004661 return response
Jon Hallc6793552016-01-19 14:18:37 -08004662 except AssertionError:
4663 main.log.exception( "" )
4664 return None
GlennRC050596c2015-11-18 17:06:41 -08004665 except TypeError:
4666 main.log.exception( self.name + ": Object not as expected" )
4667 return None
4668 except pexpect.EOF:
4669 main.log.error( self.name + ": EOF exception found" )
4670 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004671 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004672 except Exception:
4673 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004674 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004675
4676 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4677 """
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004678 Descrition: sets the controller(s) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004679
4680 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004681 Required: uri - String: The uri of the device(switch).
GlennRC050596c2015-11-18 17:06:41 -08004682 ip - String or List: The ip address of the controller.
4683 This parameter can be formed in a couple of different ways.
4684 VALID:
4685 10.0.0.1 - just the ip address
4686 tcp:10.0.0.1 - the protocol and the ip address
4687 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4688 so that you can add controllers with different
4689 protocols and ports
4690 INVALID:
4691 10.0.0.1:6653 - this is not supported by ONOS
4692
4693 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4694 port - The port number.
4695 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4696
4697 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4698 """
4699 try:
4700 cmd = "device-setcontrollers"
4701
4702 if jsonFormat:
4703 cmd += " -j"
4704 cmd += " " + uri
4705 if isinstance( ip, str ):
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004706 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08004707 for item in ip:
4708 if ":" in item:
4709 sitem = item.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004710 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08004711 cmd += " " + item
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004712 elif "." in sitem[ 1 ]:
4713 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08004714 else:
4715 main.log.error( "Malformed entry: " + item )
4716 raise TypeError
4717 else:
4718 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004719 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004720 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004721 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004722 if "Error" in response:
4723 main.log.error( response )
4724 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004725 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004726 except AssertionError:
4727 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004728 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004729 except TypeError:
4730 main.log.exception( self.name + ": Object not as expected" )
4731 return main.FALSE
4732 except pexpect.EOF:
4733 main.log.error( self.name + ": EOF exception found" )
4734 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004735 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004736 except Exception:
4737 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004738 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004739
4740 def removeDevice( self, device ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004741 '''
GlennRC20fc6522015-12-23 23:26:57 -08004742 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004743 Remove a device from ONOS by passing the uri of the device(s).
GlennRC20fc6522015-12-23 23:26:57 -08004744 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004745 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08004746 Returns:
4747 Returns main.FALSE if an exception is thrown or an error is present
4748 in the response. Otherwise, returns main.TRUE.
4749 NOTE:
4750 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004751 '''
GlennRC20fc6522015-12-23 23:26:57 -08004752 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004753 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07004754 deviceStr = device
4755 device = []
4756 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004757
4758 for d in device:
4759 time.sleep( 1 )
4760 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004761 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004762 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004763 if "Error" in response:
4764 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4765 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004766 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004767 except AssertionError:
4768 main.log.exception( "" )
4769 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004770 except TypeError:
4771 main.log.exception( self.name + ": Object not as expected" )
4772 return main.FALSE
4773 except pexpect.EOF:
4774 main.log.error( self.name + ": EOF exception found" )
4775 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004776 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004777 except Exception:
4778 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004779 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004780
4781 def removeHost( self, host ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004782 '''
GlennRC20fc6522015-12-23 23:26:57 -08004783 Description:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004784 Remove a host from ONOS by passing the id of the host(s)
GlennRC20fc6522015-12-23 23:26:57 -08004785 Parameters:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004786 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08004787 Returns:
4788 Returns main.FALSE if an exception is thrown or an error is present
4789 in the response. Otherwise, returns main.TRUE.
4790 NOTE:
4791 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004792 '''
GlennRC20fc6522015-12-23 23:26:57 -08004793 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004794 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08004795 host = list( host )
4796
4797 for h in host:
4798 time.sleep( 1 )
4799 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004800 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004801 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004802 if "Error" in response:
4803 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4804 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004805 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004806 except AssertionError:
4807 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004808 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004809 except TypeError:
4810 main.log.exception( self.name + ": Object not as expected" )
4811 return main.FALSE
4812 except pexpect.EOF:
4813 main.log.error( self.name + ": EOF exception found" )
4814 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004815 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004816 except Exception:
4817 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004818 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004819
YPZhangfebf7302016-05-24 16:45:56 -07004820 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004821 '''
GlennRCed771242016-01-13 17:02:47 -08004822 Description:
4823 Bring link down or up in the null-provider.
4824 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004825 begin - (string) One end of a device or switch.
4826 end - (string) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08004827 returns:
4828 main.TRUE if no exceptions were thrown and no Errors are
4829 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004830 '''
GlennRCed771242016-01-13 17:02:47 -08004831 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004832 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004833 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004834 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004835 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004836 if "Error" in response or "Failure" in response:
4837 main.log.error( response )
4838 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004839 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004840 except AssertionError:
4841 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004842 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004843 except TypeError:
4844 main.log.exception( self.name + ": Object not as expected" )
4845 return main.FALSE
4846 except pexpect.EOF:
4847 main.log.error( self.name + ": EOF exception found" )
4848 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004849 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004850 except Exception:
4851 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004852 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004853
Jon Hall2c8959e2016-12-16 12:17:34 -08004854 def portstate( self, dpid, port, state ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004855 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07004856 Description:
4857 Changes the state of port in an OF switch by means of the
4858 PORTSTATUS OF messages.
4859 params:
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004860 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
4861 port - (string) target port in the device. Ex: '2'
4862 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07004863 returns:
4864 main.TRUE if no exceptions were thrown and no Errors are
4865 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004866 '''
Flavio Castro82ee2f62016-06-07 15:04:12 -07004867 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08004868 state = state.lower()
4869 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07004870 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004871 response = self.sendline( cmd, showResponse=True )
4872 assert response is not None, "Error in sendline"
4873 assert "Command not found:" not in response, response
4874 if "Error" in response or "Failure" in response:
4875 main.log.error( response )
4876 return main.FALSE
4877 return main.TRUE
4878 except AssertionError:
4879 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004880 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07004881 except TypeError:
4882 main.log.exception( self.name + ": Object not as expected" )
4883 return main.FALSE
4884 except pexpect.EOF:
4885 main.log.error( self.name + ": EOF exception found" )
4886 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004887 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004888 except Exception:
4889 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004890 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004891
4892 def logSet( self, level="INFO", app="org.onosproject" ):
4893 """
4894 Set the logging level to lvl for a specific app
4895 returns main.TRUE on success
4896 returns main.FALSE if Error occurred
4897 if noExit is True, TestON will not exit, but clean up
4898 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4899 Level defaults to INFO
4900 """
4901 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004902 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004903 self.handle.expect( "onos>" )
4904
4905 response = self.handle.before
4906 if re.search( "Error", response ):
4907 return main.FALSE
4908 return main.TRUE
4909 except pexpect.TIMEOUT:
4910 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07004911 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004912 except pexpect.EOF:
4913 main.log.error( self.name + ": EOF exception found" )
4914 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004915 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004916 except Exception:
4917 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004918 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004919
4920 def getGraphDict( self, timeout=60, includeHost=False ):
4921 """
4922 Return a dictionary which describes the latest network topology data as a
4923 graph.
4924 An example of the dictionary:
4925 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4926 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4927 Each vertex should at least have an 'edges' attribute which describes the
4928 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004929 a dictionary, which maps each edge (identified by the neighbor vertex) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07004930 list of attributes.
4931 An example of the edges dictionary:
4932 'edges': { vertex2: { 'port': ..., 'weight': ... },
4933 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004934 If includeHost == True, all hosts (and host-switch links) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07004935 in topology data.
4936 """
4937 graphDict = {}
4938 try:
4939 links = self.links()
4940 links = json.loads( links )
4941 devices = self.devices()
4942 devices = json.loads( devices )
4943 idToDevice = {}
4944 for device in devices:
4945 idToDevice[ device[ 'id' ] ] = device
4946 if includeHost:
4947 hosts = self.hosts()
4948 # FIXME: support 'includeHost' argument
4949 for link in links:
4950 nodeA = link[ 'src' ][ 'device' ]
4951 nodeB = link[ 'dst' ][ 'device' ]
4952 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07004953 if nodeA not in graphDict.keys():
4954 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo82705492017-10-18 14:19:55 -07004955 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07004956 'type': idToDevice[ nodeA ][ 'type' ],
4957 'available': idToDevice[ nodeA ][ 'available' ],
4958 'role': idToDevice[ nodeA ][ 'role' ],
4959 'mfr': idToDevice[ nodeA ][ 'mfr' ],
4960 'hw': idToDevice[ nodeA ][ 'hw' ],
4961 'sw': idToDevice[ nodeA ][ 'sw' ],
4962 'serial': idToDevice[ nodeA ][ 'serial' ],
4963 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004964 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07004965 else:
4966 # Assert nodeB is not connected to any current links of nodeA
4967 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07004968 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
4969 'type': link[ 'type' ],
4970 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07004971 return graphDict
4972 except ( TypeError, ValueError ):
4973 main.log.exception( self.name + ": Object not as expected" )
4974 return None
4975 except KeyError:
4976 main.log.exception( self.name + ": KeyError exception found" )
4977 return None
4978 except AssertionError:
4979 main.log.exception( self.name + ": AssertionError exception found" )
4980 return None
4981 except pexpect.EOF:
4982 main.log.error( self.name + ": EOF exception found" )
4983 main.log.error( self.name + ": " + self.handle.before )
4984 return None
4985 except Exception:
4986 main.log.exception( self.name + ": Uncaught exception!" )
4987 return None
YPZhangcbc2a062016-07-11 10:55:44 -07004988
4989 def getIntentPerfSummary( self ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004990 '''
YPZhangcbc2a062016-07-11 10:55:44 -07004991 Send command to check intent-perf summary
4992 Returns: dictionary for intent-perf summary
4993 if something wrong, function will return None
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00004994 '''
YPZhangcbc2a062016-07-11 10:55:44 -07004995 cmd = "intent-perf -s"
4996 respDic = {}
4997 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08004998 assert resp is not None, "Error in sendline"
4999 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005000 try:
5001 # Generate the dictionary to return
5002 for l in resp.split( "\n" ):
5003 # Delete any white space in line
5004 temp = re.sub( r'\s+', '', l )
5005 temp = temp.split( ":" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005006 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07005007
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005008 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07005009 main.log.exception( self.name + ": Object not as expected" )
5010 return None
5011 except KeyError:
5012 main.log.exception( self.name + ": KeyError exception found" )
5013 return None
5014 except AssertionError:
5015 main.log.exception( self.name + ": AssertionError exception found" )
5016 return None
5017 except pexpect.EOF:
5018 main.log.error( self.name + ": EOF exception found" )
5019 main.log.error( self.name + ": " + self.handle.before )
5020 return None
5021 except Exception:
5022 main.log.exception( self.name + ": Uncaught exception!" )
5023 return None
5024 return respDic
5025
Chiyu Chengec63bde2016-11-17 18:11:36 -08005026 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005027 """
5028 Searches the latest ONOS log file for the given search term and
5029 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005030
chengchiyu08303a02016-09-08 17:40:26 -07005031 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005032 searchTerm:
5033 The string to grep from the ONOS log.
5034 startLine:
5035 The term that decides which line is the start to search the searchTerm in
5036 the karaf log. For now, startTerm only works in 'first' mode.
5037 logNum:
5038 In some extreme cases, one karaf log is not big enough to contain all the
5039 information.Because of this, search mutiply logs is necessary to capture
5040 the right result. logNum is the number of karaf logs that we need to search
5041 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005042 mode:
5043 all: return all the strings that contain the search term
5044 last: return the last string that contains the search term
5045 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005046 num: return the number of times that the searchTerm appears in the log
5047 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005048 """
5049 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005050 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005051 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005052 logPath = '/opt/onos/log/karaf.log.'
5053 logPaths = '/opt/onos/log/karaf.log'
5054 for i in range( 1, logNum ):
5055 logPaths = logPath + str( i ) + " " + logPaths
5056 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005057 if startLine:
5058 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5059 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005060 if mode == 'all':
5061 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005062 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005063 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005064 elif mode == 'first':
5065 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5066 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005067 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005068 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005069 return num
You Wang6d301d42017-04-21 10:49:33 -07005070 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005071 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005072 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005073 else:
5074 main.log.error( self.name + " unsupported mode" )
5075 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005076 before = self.sendline( cmd )
5077 before = before.splitlines()
5078 # make sure the returned list only contains the search term
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005079 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005080 return returnLines
5081 except AssertionError:
5082 main.log.error( self.name + " searchTerm is not string type" )
5083 return None
5084 except pexpect.EOF:
5085 main.log.error( self.name + ": EOF exception found" )
5086 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005087 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005088 except pexpect.TIMEOUT:
5089 main.log.error( self.name + ": TIMEOUT exception found" )
5090 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005091 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005092 except Exception:
5093 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005094 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005095
5096 def vplsShow( self, jsonFormat=True ):
5097 """
5098 Description: Returns result of onos:vpls show, which should list the
5099 configured VPLS networks and the assigned interfaces.
5100 Optional:
5101 * jsonFormat: enable json formatting of output
5102 Returns:
5103 The output of the command or None on error.
5104 """
5105 try:
5106 cmdStr = "vpls show"
5107 if jsonFormat:
5108 raise NotImplementedError
5109 cmdStr += " -j"
5110 handle = self.sendline( cmdStr )
5111 assert handle is not None, "Error in sendline"
5112 assert "Command not found:" not in handle, handle
5113 return handle
5114 except AssertionError:
5115 main.log.exception( "" )
5116 return None
5117 except TypeError:
5118 main.log.exception( self.name + ": Object not as expected" )
5119 return None
5120 except pexpect.EOF:
5121 main.log.error( self.name + ": EOF exception found" )
5122 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005123 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005124 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005125 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005126 return None
5127 except Exception:
5128 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005129 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005130
5131 def parseVplsShow( self ):
5132 """
5133 Parse the cli output of 'vpls show' into json output. This is required
5134 as there is currently no json output available.
5135 """
5136 try:
5137 output = []
5138 raw = self.vplsShow( jsonFormat=False )
5139 namePat = "VPLS name: (?P<name>\w+)"
5140 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5141 encapPat = "Encapsulation: (?P<encap>\w+)"
5142 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5143 mIter = re.finditer( pattern, raw )
5144 for match in mIter:
5145 item = {}
5146 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005147 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005148 if ifaces == [ "" ]:
5149 ifaces = []
5150 item[ 'interfaces' ] = ifaces
5151 encap = match.group( 'encap' )
5152 if encap != 'NONE':
5153 item[ 'encapsulation' ] = encap.lower()
5154 output.append( item )
5155 return output
5156 except Exception:
5157 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005158 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005159
5160 def vplsList( self, jsonFormat=True ):
5161 """
5162 Description: Returns result of onos:vpls list, which should list the
5163 configured VPLS networks.
5164 Optional:
5165 * jsonFormat: enable json formatting of output
5166 """
5167 try:
5168 cmdStr = "vpls list"
5169 if jsonFormat:
5170 raise NotImplementedError
5171 cmdStr += " -j"
5172 handle = self.sendline( cmdStr )
5173 assert handle is not None, "Error in sendline"
5174 assert "Command not found:" not in handle, handle
5175 return handle
5176 except AssertionError:
5177 main.log.exception( "" )
5178 return None
5179 except TypeError:
5180 main.log.exception( self.name + ": Object not as expected" )
5181 return None
5182 except pexpect.EOF:
5183 main.log.error( self.name + ": EOF exception found" )
5184 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005185 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005186 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005187 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005188 return None
5189 except Exception:
5190 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005191 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005192
5193 def vplsCreate( self, network ):
5194 """
5195 CLI command to create a new VPLS network.
5196 Required arguments:
5197 network - String name of the network to create.
5198 returns:
5199 main.TRUE on success and main.FALSE on failure
5200 """
5201 try:
5202 network = str( network )
5203 cmdStr = "vpls create "
5204 cmdStr += network
5205 output = self.sendline( cmdStr )
5206 assert output is not None, "Error in sendline"
5207 assert "Command not found:" not in output, output
5208 assert "Error executing command" not in output, output
5209 assert "VPLS already exists:" not in output, output
5210 return main.TRUE
5211 except AssertionError:
5212 main.log.exception( "" )
5213 return main.FALSE
5214 except TypeError:
5215 main.log.exception( self.name + ": Object not as expected" )
5216 return main.FALSE
5217 except pexpect.EOF:
5218 main.log.error( self.name + ": EOF exception found" )
5219 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005220 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005221 except Exception:
5222 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005223 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005224
5225 def vplsDelete( self, network ):
5226 """
5227 CLI command to delete a VPLS network.
5228 Required arguments:
5229 network - Name of the network to delete.
5230 returns:
5231 main.TRUE on success and main.FALSE on failure
5232 """
5233 try:
5234 network = str( network )
5235 cmdStr = "vpls delete "
5236 cmdStr += network
5237 output = self.sendline( cmdStr )
5238 assert output is not None, "Error in sendline"
5239 assert "Command not found:" not in output, output
5240 assert "Error executing command" not in output, output
5241 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005242 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005243 return main.TRUE
5244 except AssertionError:
5245 main.log.exception( "" )
5246 return main.FALSE
5247 except TypeError:
5248 main.log.exception( self.name + ": Object not as expected" )
5249 return main.FALSE
5250 except pexpect.EOF:
5251 main.log.error( self.name + ": EOF exception found" )
5252 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005253 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005254 except Exception:
5255 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005256 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005257
5258 def vplsAddIface( self, network, iface ):
5259 """
5260 CLI command to add an interface to a VPLS network.
5261 Required arguments:
5262 network - Name of the network to add the interface to.
5263 iface - The ONOS name for an interface.
5264 returns:
5265 main.TRUE on success and main.FALSE on failure
5266 """
5267 try:
5268 network = str( network )
5269 iface = str( iface )
5270 cmdStr = "vpls add-if "
5271 cmdStr += network + " " + iface
5272 output = self.sendline( cmdStr )
5273 assert output is not None, "Error in sendline"
5274 assert "Command not found:" not in output, output
5275 assert "Error executing command" not in output, output
5276 assert "already associated to network" not in output, output
5277 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005278 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005279 return main.TRUE
5280 except AssertionError:
5281 main.log.exception( "" )
5282 return main.FALSE
5283 except TypeError:
5284 main.log.exception( self.name + ": Object not as expected" )
5285 return main.FALSE
5286 except pexpect.EOF:
5287 main.log.error( self.name + ": EOF exception found" )
5288 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005289 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005290 except Exception:
5291 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005292 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005293
5294 def vplsRemIface( self, network, iface ):
5295 """
5296 CLI command to remove an interface from a VPLS network.
5297 Required arguments:
5298 network - Name of the network to remove the interface from.
5299 iface - Name of the interface to remove.
5300 returns:
5301 main.TRUE on success and main.FALSE on failure
5302 """
5303 try:
5304 iface = str( iface )
5305 cmdStr = "vpls rem-if "
5306 cmdStr += network + " " + iface
5307 output = self.sendline( cmdStr )
5308 assert output is not None, "Error in sendline"
5309 assert "Command not found:" not in output, output
5310 assert "Error executing command" not in output, output
5311 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005312 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005313 return main.TRUE
5314 except AssertionError:
5315 main.log.exception( "" )
5316 return main.FALSE
5317 except TypeError:
5318 main.log.exception( self.name + ": Object not as expected" )
5319 return main.FALSE
5320 except pexpect.EOF:
5321 main.log.error( self.name + ": EOF exception found" )
5322 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005323 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005324 except Exception:
5325 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005326 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005327
5328 def vplsClean( self ):
5329 """
5330 Description: Clears the VPLS app configuration.
5331 Returns: main.TRUE on success and main.FALSE on failure
5332 """
5333 try:
5334 cmdStr = "vpls clean"
5335 handle = self.sendline( cmdStr )
5336 assert handle is not None, "Error in sendline"
5337 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005338 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005339 return handle
5340 except AssertionError:
5341 main.log.exception( "" )
5342 return main.FALSE
5343 except TypeError:
5344 main.log.exception( self.name + ": Object not as expected" )
5345 return main.FALSE
5346 except pexpect.EOF:
5347 main.log.error( self.name + ": EOF exception found" )
5348 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005349 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005350 except Exception:
5351 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005352 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005353
5354 def vplsSetEncap( self, network, encapType ):
5355 """
5356 CLI command to add an interface to a VPLS network.
5357 Required arguments:
5358 network - Name of the network to create.
5359 encapType - Type of encapsulation.
5360 returns:
5361 main.TRUE on success and main.FALSE on failure
5362 """
5363 try:
5364 network = str( network )
5365 encapType = str( encapType ).upper()
5366 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5367 cmdStr = "vpls set-encap "
5368 cmdStr += network + " " + encapType
5369 output = self.sendline( cmdStr )
5370 assert output is not None, "Error in sendline"
5371 assert "Command not found:" not in output, output
5372 assert "Error executing command" not in output, output
5373 assert "already associated to network" not in output, output
5374 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005375 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005376 return main.TRUE
5377 except AssertionError:
5378 main.log.exception( "" )
5379 return main.FALSE
5380 except TypeError:
5381 main.log.exception( self.name + ": Object not as expected" )
5382 return main.FALSE
5383 except pexpect.EOF:
5384 main.log.error( self.name + ": EOF exception found" )
5385 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005386 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005387 except Exception:
5388 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005389 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005390
5391 def interfaces( self, jsonFormat=True ):
5392 """
5393 Description: Returns result of interfaces command.
5394 Optional:
5395 * jsonFormat: enable json formatting of output
5396 Returns:
5397 The output of the command or None on error.
5398 """
5399 try:
5400 cmdStr = "interfaces"
5401 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005402 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005403 cmdStr += " -j"
5404 handle = self.sendline( cmdStr )
5405 assert handle is not None, "Error in sendline"
5406 assert "Command not found:" not in handle, handle
5407 return handle
5408 except AssertionError:
5409 main.log.exception( "" )
5410 return None
5411 except TypeError:
5412 main.log.exception( self.name + ": Object not as expected" )
5413 return None
5414 except pexpect.EOF:
5415 main.log.error( self.name + ": EOF exception found" )
5416 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005417 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005418 except NotImplementedError:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005419 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005420 return None
5421 except Exception:
5422 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005423 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005424
5425 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005426 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005427 Get the timestamp of searchTerm from karaf log.
5428
5429 Arguments:
5430 splitTerm_before and splitTerm_after:
5431
5432 The terms that split the string that contains the timeStamp of
5433 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5434 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5435 and the splitTerm_after is "x"
5436
5437 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005438 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo4d5f1d02017-10-13 20:23:57 +00005439 '''
Chiyu Chengec63bde2016-11-17 18:11:36 -08005440 if logNum < 0:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005441 main.log.error( "Get wrong log number ")
Chiyu Chengec63bde2016-11-17 18:11:36 -08005442 return main.ERROR
5443 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005444 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005445 main.log.warn( "Captured timestamp string is empty" )
5446 return main.ERROR
5447 lines = lines[ 0 ]
5448 try:
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005449 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005450 # get the target value
5451 line = lines.split( splitTerm_before )
5452 key = line[ 1 ].split( splitTerm_after )
5453 return int( key[ 0 ] )
5454 except IndexError:
5455 main.log.warn( "Index Error!" )
5456 return main.ERROR
5457 except AssertionError:
5458 main.log.warn( "Search Term Not Found " )
5459 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005460
5461 def workQueueAdd( self, queueName, value ):
5462 """
5463 CLI command to add a string to the specified Work Queue.
5464 This function uses the distributed primitives test app, which
5465 gives some cli access to distributed primitives for testing
5466 purposes only.
5467
5468 Required arguments:
5469 queueName - The name of the queue to add to
5470 value - The value to add to the queue
5471 returns:
5472 main.TRUE on success, main.FALSE on failure and
5473 main.ERROR on error.
5474 """
5475 try:
5476 queueName = str( queueName )
5477 value = str( value )
5478 prefix = "work-queue-test"
5479 operation = "add"
5480 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5481 output = self.distPrimitivesSend( cmdStr )
5482 if "Invalid operation name" in output:
5483 main.log.warn( output )
5484 return main.ERROR
5485 elif "Done" in output:
5486 return main.TRUE
5487 except TypeError:
5488 main.log.exception( self.name + ": Object not as expected" )
5489 return main.ERROR
5490 except Exception:
5491 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005492 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005493
5494 def workQueueAddMultiple( self, queueName, value1, value2 ):
5495 """
5496 CLI command to add two strings to the specified Work Queue.
5497 This function uses the distributed primitives test app, which
5498 gives some cli access to distributed primitives for testing
5499 purposes only.
5500
5501 Required arguments:
5502 queueName - The name of the queue to add to
5503 value1 - The first value to add to the queue
5504 value2 - The second value to add to the queue
5505 returns:
5506 main.TRUE on success, main.FALSE on failure and
5507 main.ERROR on error.
5508 """
5509 try:
5510 queueName = str( queueName )
5511 value1 = str( value1 )
5512 value2 = str( value2 )
5513 prefix = "work-queue-test"
5514 operation = "addMultiple"
5515 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5516 output = self.distPrimitivesSend( cmdStr )
5517 if "Invalid operation name" in output:
5518 main.log.warn( output )
5519 return main.ERROR
5520 elif "Done" in output:
5521 return main.TRUE
5522 except TypeError:
5523 main.log.exception( self.name + ": Object not as expected" )
5524 return main.ERROR
5525 except Exception:
5526 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005527 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005528
5529 def workQueueTakeAndComplete( self, queueName, number=1 ):
5530 """
5531 CLI command to take a value from the specified Work Queue and compelte it.
5532 This function uses the distributed primitives test app, which
5533 gives some cli access to distributed primitives for testing
5534 purposes only.
5535
5536 Required arguments:
5537 queueName - The name of the queue to add to
5538 number - The number of items to take and complete
5539 returns:
5540 main.TRUE on success, main.FALSE on failure and
5541 main.ERROR on error.
5542 """
5543 try:
5544 queueName = str( queueName )
5545 number = str( int( number ) )
5546 prefix = "work-queue-test"
5547 operation = "takeAndComplete"
5548 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5549 output = self.distPrimitivesSend( cmdStr )
5550 if "Invalid operation name" in output:
5551 main.log.warn( output )
5552 return main.ERROR
5553 elif "Done" in output:
5554 return main.TRUE
5555 except TypeError:
5556 main.log.exception( self.name + ": Object not as expected" )
5557 return main.ERROR
5558 except Exception:
5559 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005560 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005561
5562 def workQueueDestroy( self, queueName ):
5563 """
5564 CLI command to destroy the specified Work Queue.
5565 This function uses the distributed primitives test app, which
5566 gives some cli access to distributed primitives for testing
5567 purposes only.
5568
5569 Required arguments:
5570 queueName - The name of the queue to add to
5571 returns:
5572 main.TRUE on success, main.FALSE on failure and
5573 main.ERROR on error.
5574 """
5575 try:
5576 queueName = str( queueName )
5577 prefix = "work-queue-test"
5578 operation = "destroy"
5579 cmdStr = " ".join( [ prefix, queueName, operation ] )
5580 output = self.distPrimitivesSend( cmdStr )
5581 if "Invalid operation name" in output:
5582 main.log.warn( output )
5583 return main.ERROR
5584 return main.TRUE
5585 except TypeError:
5586 main.log.exception( self.name + ": Object not as expected" )
5587 return main.ERROR
5588 except Exception:
5589 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005590 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005591
5592 def workQueueTotalPending( self, queueName ):
5593 """
5594 CLI command to get the Total Pending items of the specified Work Queue.
5595 This function uses the distributed primitives test app, which
5596 gives some cli access to distributed primitives for testing
5597 purposes only.
5598
5599 Required arguments:
5600 queueName - The name of the queue to add to
5601 returns:
5602 The number of Pending items in the specified work queue or
5603 None on error
5604 """
5605 try:
5606 queueName = str( queueName )
5607 prefix = "work-queue-test"
5608 operation = "totalPending"
5609 cmdStr = " ".join( [ prefix, queueName, operation ] )
5610 output = self.distPrimitivesSend( cmdStr )
5611 pattern = r'\d+'
5612 if "Invalid operation name" in output:
5613 main.log.warn( output )
5614 return None
5615 else:
5616 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005617 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005618 except ( AttributeError, TypeError ):
5619 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5620 return None
5621 except Exception:
5622 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005623 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005624
5625 def workQueueTotalCompleted( self, queueName ):
5626 """
5627 CLI command to get the Total Completed items of the specified Work Queue.
5628 This function uses the distributed primitives test app, which
5629 gives some cli access to distributed primitives for testing
5630 purposes only.
5631
5632 Required arguments:
5633 queueName - The name of the queue to add to
5634 returns:
5635 The number of complete items in the specified work queue or
5636 None on error
5637 """
5638 try:
5639 queueName = str( queueName )
5640 prefix = "work-queue-test"
5641 operation = "totalCompleted"
5642 cmdStr = " ".join( [ prefix, queueName, operation ] )
5643 output = self.distPrimitivesSend( cmdStr )
5644 pattern = r'\d+'
5645 if "Invalid operation name" in output:
5646 main.log.warn( output )
5647 return None
5648 else:
5649 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005650 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005651 except ( AttributeError, TypeError ):
5652 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5653 return None
5654 except Exception:
5655 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005656 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005657
5658 def workQueueTotalInProgress( self, queueName ):
5659 """
5660 CLI command to get the Total In Progress items of the specified Work Queue.
5661 This function uses the distributed primitives test app, which
5662 gives some cli access to distributed primitives for testing
5663 purposes only.
5664
5665 Required arguments:
5666 queueName - The name of the queue to add to
5667 returns:
5668 The number of In Progress items in the specified work queue or
5669 None on error
5670 """
5671 try:
5672 queueName = str( queueName )
5673 prefix = "work-queue-test"
5674 operation = "totalInProgress"
5675 cmdStr = " ".join( [ prefix, queueName, operation ] )
5676 output = self.distPrimitivesSend( cmdStr )
5677 pattern = r'\d+'
5678 if "Invalid operation name" in output:
5679 main.log.warn( output )
5680 return None
5681 else:
5682 match = re.search( pattern, output )
Jeremy Ronquillo82705492017-10-18 14:19:55 -07005683 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005684 except ( AttributeError, TypeError ):
5685 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5686 return None
5687 except Exception:
5688 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005689 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005690
5691 def events( self, args='-a' ):
5692 """
5693 Description: Returns events -a command output
5694 Optional:
5695 add other arguments
5696 """
5697 try:
5698 cmdStr = "events"
5699 if args:
5700 cmdStr += " " + args
5701 handle = self.sendline( cmdStr )
5702 assert handle is not None, "Error in sendline"
5703 assert "Command not found:" not in handle, handle
5704 return handle
5705 except AssertionError:
5706 main.log.exception( "" )
5707 return None
5708 except TypeError:
5709 main.log.exception( self.name + ": Object not as expected" )
5710 return None
5711 except pexpect.EOF:
5712 main.log.error( self.name + ": EOF exception found" )
5713 main.log.error( self.name + ": " + self.handle.before )
5714 main.cleanAndExit()
5715 except Exception:
5716 main.log.exception( self.name + ": Uncaught exception!" )
5717 main.cleanAndExit()
5718
5719 def getMaster( self, deviceID ):
5720 """
5721 Description: Obtains current master using "roles" command for a specific deviceID
5722 """
5723 try:
5724 return str( self.getRole( deviceID )[ 'master' ] )
5725 except AssertionError:
5726 main.log.exception( "" )
5727 return None
5728 except TypeError:
5729 main.log.exception( self.name + ": Object not as expected" )
5730 return None
5731 except pexpect.EOF:
5732 main.log.error( self.name + ": EOF exception found" )
5733 main.log.error( self.name + ": " + self.handle.before )
5734 main.cleanAndExit()
5735 except Exception:
5736 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lime6fe3c42017-10-18 16:28:40 -07005737 main.cleanAndExit()