blob: 56e728b8d1ad6adb7431a6911f483d7a09059983 [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 Ronquillo23fb2162017-09-15 14:59:57 -07005Copyright 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 Ronquillo23fb2162017-09-15 14:59:57 -070014 ( 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 Ronquillob27ce4c2017-07-17 12:41:28 -070024"""
andrewonlab95ce8322014-10-13 14:12:04 -040025This driver enters the onos> prompt to issue commands.
26
kelvin8ec71442015-01-15 16:57:00 -080027Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -040028functions and document properly.
29
30If you are a contributor to the driver, please
31list your email here for future contact:
32
33jhall@onlab.us
34andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040035shreya@onlab.us
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +000036jeremyr@opennetworking.org
kelvin8ec71442015-01-15 16:57:00 -080037"""
andrewonlab95ce8322014-10-13 14:12:04 -040038import pexpect
39import re
Jon Hall30b82fa2015-03-04 17:15:43 -080040import json
41import types
Jon Hallbd16b922015-03-26 17:53:15 -070042import time
kelvin-onlaba4074292015-07-09 15:19:49 -070043import os
andrewonlab95ce8322014-10-13 14:12:04 -040044from drivers.common.clidriver import CLI
You Wangdb8cd0a2016-05-26 15:19:45 -070045from core.graph import Graph
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -070046from cStringIO import StringIO
47from itertools import izip
andrewonlab95ce8322014-10-13 14:12:04 -040048
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -070049
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 Ronquillo23fb2162017-09-15 14:59:57 -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 Ronquillo23fb2162017-09-15 14:59:57 -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 Ronquillo23fb2162017-09-15 14:59:57 -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 Ronquillo23fb2162017-09-15 14:59:57 -0700167 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 Ronquillo23fb2162017-09-15 14:59:57 -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 Ronquillo23fb2162017-09-15 14:59:57 -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 Ronquillo23fb2162017-09-15 14:59:57 -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 """
suibin zhang116647a2016-05-06 16:30:09 -0700355 try:
356 self.handle.sendline( "" )
357 x = self.handle.expect( [
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700358 self.prompt, "onos>" ], commandlineTimeout )
suibin zhang116647a2016-05-06 16:30:09 -0700359
360 if x == 1:
361 main.log.info( "ONOS cli is already running" )
362 return main.TRUE
363
364 # Wait for onos start ( -w ) and enter onos cli
365 self.handle.sendline( "/opt/onos/bin/onos" )
366 i = self.handle.expect( [
367 "onos>",
368 pexpect.TIMEOUT ], onosStartTimeout )
369
370 if i == 0:
371 main.log.info( self.name + " CLI Started successfully" )
372 if karafTimeout:
373 self.handle.sendline(
374 "config:property-set -p org.apache.karaf.shell\
375 sshIdleTimeout " +
376 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700377 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700378 self.handle.sendline( "/opt/onos/bin/onos" )
379 self.handle.expect( "onos>" )
380 return main.TRUE
381 else:
382 # If failed, send ctrl+c to process and try again
383 main.log.info( "Starting CLI failed. Retrying..." )
384 self.handle.send( "\x03" )
385 self.handle.sendline( "/opt/onos/bin/onos" )
386 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
387 timeout=30 )
388 if i == 0:
389 main.log.info( self.name + " CLI Started " +
390 "successfully after retry attempt" )
391 if karafTimeout:
392 self.handle.sendline(
393 "config:property-set -p org.apache.karaf.shell\
394 sshIdleTimeout " +
395 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700396 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700397 self.handle.sendline( "/opt/onos/bin/onos" )
398 self.handle.expect( "onos>" )
399 return main.TRUE
400 else:
401 main.log.error( "Connection to CLI " +
402 self.name + " timeout" )
403 return main.FALSE
404
405 except TypeError:
406 main.log.exception( self.name + ": Object not as expected" )
407 return None
408 except pexpect.EOF:
409 main.log.error( self.name + ": EOF exception found" )
410 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700411 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700412 except Exception:
413 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700414 main.cleanAndExit()
suibin zhang116647a2016-05-06 16:30:09 -0700415
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800416 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800417 """
418 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800419 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800420 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700421 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800422 Available level: DEBUG, TRACE, INFO, WARN, ERROR
423 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800424 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800425 """
426 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800427 lvlStr = ""
428 if level:
429 lvlStr = "--level=" + level
430
kelvin-onlab338f5512015-02-06 10:53:16 -0800431 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700432 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800433 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800434
kelvin-onlab9f541032015-02-04 16:19:53 -0800435 response = self.handle.before
436 if re.search( "Error", response ):
437 return main.FALSE
438 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700439 except pexpect.TIMEOUT:
440 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700441 if noExit:
442 main.cleanup()
443 return None
444 else:
Devin Lim44075962017-08-11 10:56:37 -0700445 main.cleanAndExit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800446 except pexpect.EOF:
447 main.log.error( self.name + ": EOF exception found" )
448 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700449 if noExit:
450 main.cleanup()
451 return None
452 else:
Devin Lim44075962017-08-11 10:56:37 -0700453 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800454 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800455 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700456 if noExit:
457 main.cleanup()
458 return None
459 else:
Devin Lim44075962017-08-11 10:56:37 -0700460 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -0400461
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700462 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, dollarSign=False ):
kelvin8ec71442015-01-15 16:57:00 -0800463 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800464 Send a completely user specified string to
465 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400466 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800467
YPZhang14a4aa92016-07-15 13:37:15 -0700468 if noExit is True, TestON will not exit, and return None
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700469 if dollarSign is True, TestON will not expect for '$' as a new CLI or onos> prompt
470 since '$' can be in the output.
YPZhangebf9eb52016-05-12 15:20:24 -0700471
andrewonlaba18f6bf2014-10-13 19:31:54 -0400472 Warning: There are no sanity checking to commands
473 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800474
kelvin8ec71442015-01-15 16:57:00 -0800475 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400476 try:
Jon Halla495f562016-05-16 18:03:26 -0700477 # Try to reconnect if disconnected from cli
478 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700479 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ] )
Jon Halla495f562016-05-16 18:03:26 -0700480 if i == 1:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700481 main.log.error( self.name + ": onos cli session closed. " )
Jon Halla495f562016-05-16 18:03:26 -0700482 if self.onosIp:
483 main.log.warn( "Trying to reconnect " + self.onosIp )
484 reconnectResult = self.startOnosCli( self.onosIp )
485 if reconnectResult:
486 main.log.info( self.name + ": onos cli session reconnected." )
487 else:
488 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700489 if noExit:
490 return None
491 else:
Devin Lim44075962017-08-11 10:56:37 -0700492 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700493 else:
Devin Lim44075962017-08-11 10:56:37 -0700494 main.cleanAndExit()
Jon Halla495f562016-05-16 18:03:26 -0700495 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700496 main.log.warn( "Timeout when testing cli responsiveness" )
497 main.log.debug( self.handle.before )
498 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700499 self.handle.expect( "onos>" )
500
Jon Hall14a03b52016-05-11 12:07:30 -0700501 if debug:
502 # NOTE: This adds and average of .4 seconds per call
503 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700504 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800505 self.handle.sendline( cmdStr )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700506 if dollarSign:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700507 i = self.handle.expect( [ "onos>" ], timeout )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700508 else:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700509 i = self.handle.expect( [ "onos>", self.prompt ], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800510 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800511 # TODO: do something with i
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700512 main.log.info( "Command '" + str(cmdStr) + "' sent to "
Jon Hallc6793552016-01-19 14:18:37 -0800513 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700514 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700515 main.log.debug( self.name + ": Raw output" )
516 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700517
518 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800519 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800520 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700521 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700522 main.log.debug( self.name + ": ansiEscape output" )
523 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700524
kelvin-onlabfb521662015-02-27 09:52:40 -0800525 # Remove extra return chars that get added
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700526 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700527 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700528 main.log.debug( self.name + ": Removed extra returns " +
529 "from output" )
530 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700531
532 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800533 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700534 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700535 main.log.debug( self.name + ": parsed and stripped output" )
536 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700537
Jon Hall63604932015-02-26 17:09:50 -0800538 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700539 output = response.split( cmdStr.strip(), 1 )
540 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700541 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700542 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700543 main.log.debug( self.name + ": " + repr( r ) )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700544 output = output[ 1 ].strip()
GlennRC85870432015-11-23 11:45:51 -0800545 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800546 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800547 return output
GlennRCed771242016-01-13 17:02:47 -0800548 except pexpect.TIMEOUT:
549 main.log.error( self.name + ":ONOS timeout" )
550 if debug:
551 main.log.debug( self.handle.before )
552 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700553 except IndexError:
554 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700555 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700556 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800557 except TypeError:
558 main.log.exception( self.name + ": Object not as expected" )
559 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400560 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800561 main.log.error( self.name + ": EOF exception found" )
562 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700563 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700564 return None
565 else:
Devin Lim44075962017-08-11 10:56:37 -0700566 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800567 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800568 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700569 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700570 return None
571 else:
Devin Lim44075962017-08-11 10:56:37 -0700572 main.cleanAndExit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400573
kelvin8ec71442015-01-15 16:57:00 -0800574 # IMPORTANT NOTE:
575 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800576 # the cli command changing 'a:b' with 'aB'.
577 # Ex ) onos:topology > onosTopology
578 # onos:links > onosLinks
579 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800580
kelvin-onlabd3b64892015-01-20 13:26:24 -0800581 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800582 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400583 Adds a new cluster node by ID and address information.
584 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800585 * nodeId
586 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400587 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800588 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800589 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400590 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800591 cmdStr = "add-node " + str( nodeId ) + " " +\
592 str( ONOSIp ) + " " + str( tcpPort )
593 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700594 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800595 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800596 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800597 main.log.error( "Error in adding node" )
598 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800599 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400600 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800601 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400602 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800603 except AssertionError:
604 main.log.exception( "" )
605 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800606 except TypeError:
607 main.log.exception( self.name + ": Object not as expected" )
608 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400609 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800610 main.log.error( self.name + ": EOF exception found" )
611 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700612 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800613 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800614 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700615 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400616
kelvin-onlabd3b64892015-01-20 13:26:24 -0800617 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800618 """
andrewonlab86dc3082014-10-13 18:18:38 -0400619 Removes a cluster by ID
620 Issues command: 'remove-node [<node-id>]'
621 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800622 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800623 """
andrewonlab86dc3082014-10-13 18:18:38 -0400624 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400625
kelvin-onlabd3b64892015-01-20 13:26:24 -0800626 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700627 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700628 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800629 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700630 if re.search( "Error", handle ):
631 main.log.error( "Error in removing node" )
632 main.log.error( handle )
633 return main.FALSE
634 else:
635 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800636 except AssertionError:
637 main.log.exception( "" )
638 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800639 except TypeError:
640 main.log.exception( self.name + ": Object not as expected" )
641 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400642 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800643 main.log.error( self.name + ": EOF exception found" )
644 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700645 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800646 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800647 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700648 main.cleanAndExit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400649
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700650 def nodes( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800651 """
andrewonlab7c211572014-10-15 16:45:20 -0400652 List the nodes currently visible
653 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700654 Optional argument:
655 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800656 """
andrewonlab7c211572014-10-15 16:45:20 -0400657 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700658 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700659 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700660 cmdStr += " -j"
661 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700662 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800663 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700664 return output
Jon Hallc6793552016-01-19 14:18:37 -0800665 except AssertionError:
666 main.log.exception( "" )
667 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800668 except TypeError:
669 main.log.exception( self.name + ": Object not as expected" )
670 return None
andrewonlab7c211572014-10-15 16:45:20 -0400671 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800672 main.log.error( self.name + ": EOF exception found" )
673 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700674 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800675 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800676 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700677 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400678
kelvin8ec71442015-01-15 16:57:00 -0800679 def topology( self ):
680 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700681 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700682 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700683 Return:
684 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800685 """
andrewonlab95ce8322014-10-13 14:12:04 -0400686 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700687 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800688 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800689 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800690 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700691 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400692 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800693 except AssertionError:
694 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800695 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800696 except TypeError:
697 main.log.exception( self.name + ": Object not as expected" )
698 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400699 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800700 main.log.error( self.name + ": EOF exception found" )
701 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700702 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800703 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800704 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700705 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -0800706
jenkins7ead5a82015-03-13 10:28:21 -0700707 def deviceRemove( self, deviceId ):
708 """
709 Removes particular device from storage
710
711 TODO: refactor this function
712 """
713 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700714 cmdStr = "device-remove " + str( deviceId )
715 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800716 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800717 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700718 if re.search( "Error", handle ):
719 main.log.error( "Error in removing device" )
720 main.log.error( handle )
721 return main.FALSE
722 else:
723 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800724 except AssertionError:
725 main.log.exception( "" )
726 return None
jenkins7ead5a82015-03-13 10:28:21 -0700727 except TypeError:
728 main.log.exception( self.name + ": Object not as expected" )
729 return None
730 except pexpect.EOF:
731 main.log.error( self.name + ": EOF exception found" )
732 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700733 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700734 except Exception:
735 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700736 main.cleanAndExit()
jenkins7ead5a82015-03-13 10:28:21 -0700737
kelvin-onlabd3b64892015-01-20 13:26:24 -0800738 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800739 """
Jon Hall7b02d952014-10-17 20:14:54 -0400740 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400741 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800742 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800743 """
andrewonlab86dc3082014-10-13 18:18:38 -0400744 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700745 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800746 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700747 cmdStr += " -j"
748 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800749 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800750 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700751 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800752 except AssertionError:
753 main.log.exception( "" )
754 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800755 except TypeError:
756 main.log.exception( self.name + ": Object not as expected" )
757 return None
andrewonlab7c211572014-10-15 16:45:20 -0400758 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800759 main.log.error( self.name + ": EOF exception found" )
760 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700761 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800762 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800763 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700764 main.cleanAndExit()
andrewonlab7c211572014-10-15 16:45:20 -0400765
kelvin-onlabd3b64892015-01-20 13:26:24 -0800766 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800767 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800768 This balances the devices across all controllers
769 by issuing command: 'onos> onos:balance-masters'
770 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800771 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800772 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700774 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800775 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800776 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700777 if re.search( "Error", handle ):
778 main.log.error( "Error in balancing masters" )
779 main.log.error( handle )
780 return main.FALSE
781 else:
782 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800783 except AssertionError:
784 main.log.exception( "" )
785 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800786 except TypeError:
787 main.log.exception( self.name + ": Object not as expected" )
788 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800789 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800790 main.log.error( self.name + ": EOF exception found" )
791 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700792 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800793 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800794 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700795 main.cleanAndExit()
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800796
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700797 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700798 """
799 Returns the output of the masters command.
800 Optional argument:
801 * jsonFormat - boolean indicating if you want output in json
802 """
803 try:
804 cmdStr = "onos:masters"
805 if jsonFormat:
806 cmdStr += " -j"
807 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700808 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800809 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700810 return output
Jon Hallc6793552016-01-19 14:18:37 -0800811 except AssertionError:
812 main.log.exception( "" )
813 return None
acsmars24950022015-07-30 18:00:43 -0700814 except TypeError:
815 main.log.exception( self.name + ": Object not as expected" )
816 return None
817 except pexpect.EOF:
818 main.log.error( self.name + ": EOF exception found" )
819 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700820 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700821 except Exception:
822 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700823 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700824
Jon Hallc6793552016-01-19 14:18:37 -0800825 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700826 """
827 Uses the master command to check that the devices' leadership
828 is evenly divided
829
830 Dependencies: checkMasters() and summary()
831
Jon Hall6509dbf2016-06-21 17:01:17 -0700832 Returns main.TRUE if the devices are balanced
833 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700834 Exits on Exception
835 Returns None on TypeError
836 """
837 try:
Jon Hallc6793552016-01-19 14:18:37 -0800838 summaryOutput = self.summary()
839 totalDevices = json.loads( summaryOutput )[ "devices" ]
840 except ( TypeError, ValueError ):
841 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
842 return None
843 try:
acsmars24950022015-07-30 18:00:43 -0700844 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800845 mastersOutput = self.checkMasters()
846 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700847 first = masters[ 0 ][ "size" ]
848 for master in masters:
849 totalOwnedDevices += master[ "size" ]
850 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
851 main.log.error( "Mastership not balanced" )
852 main.log.info( "\n" + self.checkMasters( False ) )
853 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700854 main.log.info( "Mastership balanced between " +
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -0700855 str( len( masters ) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700856 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800857 except ( TypeError, ValueError ):
858 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700859 return None
860 except pexpect.EOF:
861 main.log.error( self.name + ": EOF exception found" )
862 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700863 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700864 except Exception:
865 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700866 main.cleanAndExit()
acsmars24950022015-07-30 18:00:43 -0700867
YPZhangfebf7302016-05-24 16:45:56 -0700868 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800869 """
Jon Halle8217482014-10-17 13:49:14 -0400870 Lists all core links
871 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800872 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800873 """
Jon Halle8217482014-10-17 13:49:14 -0400874 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700875 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800876 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700877 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700878 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800879 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800880 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700881 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800882 except AssertionError:
883 main.log.exception( "" )
884 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800885 except TypeError:
886 main.log.exception( self.name + ": Object not as expected" )
887 return None
Jon Halle8217482014-10-17 13:49:14 -0400888 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800889 main.log.error( self.name + ": EOF exception found" )
890 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700891 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800892 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800893 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700894 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400895
kelvin-onlabd3b64892015-01-20 13:26:24 -0800896 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800897 """
Jon Halle8217482014-10-17 13:49:14 -0400898 Lists all ports
899 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800900 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800901 """
Jon Halle8217482014-10-17 13:49:14 -0400902 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700903 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800904 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700905 cmdStr += " -j"
906 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800907 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800908 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700909 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800910 except AssertionError:
911 main.log.exception( "" )
912 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800913 except TypeError:
914 main.log.exception( self.name + ": Object not as expected" )
915 return None
Jon Halle8217482014-10-17 13:49:14 -0400916 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800917 main.log.error( self.name + ": EOF exception found" )
918 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700919 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800920 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800921 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700922 main.cleanAndExit()
Jon Halle8217482014-10-17 13:49:14 -0400923
kelvin-onlabd3b64892015-01-20 13:26:24 -0800924 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800925 """
Jon Hall983a1702014-10-28 18:44:22 -0400926 Lists all devices and the controllers with roles assigned to them
927 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800928 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800929 """
andrewonlab7c211572014-10-15 16:45:20 -0400930 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700931 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800932 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700933 cmdStr += " -j"
934 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800935 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800936 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700937 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800938 except AssertionError:
939 main.log.exception( "" )
940 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800941 except TypeError:
942 main.log.exception( self.name + ": Object not as expected" )
943 return None
Jon Hall983a1702014-10-28 18:44:22 -0400944 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800945 main.log.error( self.name + ": EOF exception found" )
946 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700947 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800948 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800949 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700950 main.cleanAndExit()
Jon Hall983a1702014-10-28 18:44:22 -0400951
kelvin-onlabd3b64892015-01-20 13:26:24 -0800952 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800953 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800954 Given the a string containing the json representation of the "roles"
955 cli command and a partial or whole device id, returns a json object
956 containing the roles output for the first device whose id contains
957 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400958
959 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -0800960 A dict of the role assignments for the given device or
961 None if no match
kelvin8ec71442015-01-15 16:57:00 -0800962 """
Jon Hall983a1702014-10-28 18:44:22 -0400963 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800964 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -0400965 return None
966 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800967 rawRoles = self.roles()
968 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800969 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800970 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800971 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800972 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -0400973 return device
974 return None
Jon Hallc6793552016-01-19 14:18:37 -0800975 except ( TypeError, ValueError ):
976 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -0800977 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400978 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800979 main.log.error( self.name + ": EOF exception found" )
980 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -0700981 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800982 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800983 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -0700984 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -0800985
kelvin-onlabd3b64892015-01-20 13:26:24 -0800986 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -0800987 """
Jon Hall94fd0472014-12-08 11:52:42 -0800988 Iterates through each device and checks if there is a master assigned
989 Returns: main.TRUE if each device has a master
990 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -0800991 """
Jon Hall94fd0472014-12-08 11:52:42 -0800992 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800993 rawRoles = self.roles()
994 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -0800995 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -0800996 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -0800997 # print device
998 if device[ 'master' ] == "none":
999 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001000 return main.FALSE
1001 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001002 except ( TypeError, ValueError ):
1003 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001004 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001005 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001006 main.log.error( self.name + ": EOF exception found" )
1007 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001008 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001009 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001010 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001011 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08001012
kelvin-onlabd3b64892015-01-20 13:26:24 -08001013 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001014 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001015 Returns string of paths, and the cost.
1016 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001017 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001018 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001019 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1020 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001021 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001022 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001023 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001024 main.log.error( "Error in getting paths" )
1025 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001026 else:
kelvin8ec71442015-01-15 16:57:00 -08001027 path = handle.split( ";" )[ 0 ]
1028 cost = handle.split( ";" )[ 1 ]
1029 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001030 except AssertionError:
1031 main.log.exception( "" )
1032 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001033 except TypeError:
1034 main.log.exception( self.name + ": Object not as expected" )
1035 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001036 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001037 main.log.error( self.name + ": EOF exception found" )
1038 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001039 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001040 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001041 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001042 main.cleanAndExit()
Jon Hallffb386d2014-11-21 13:43:38 -08001043
kelvin-onlabd3b64892015-01-20 13:26:24 -08001044 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001045 """
Jon Hallffb386d2014-11-21 13:43:38 -08001046 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001047 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001048 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001049 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001050 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001051 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001052 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001053 cmdStr += " -j"
1054 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001055 if handle:
1056 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001057 # TODO: Maybe make this less hardcoded
1058 # ConsistentMap Exceptions
1059 assert "org.onosproject.store.service" not in handle
1060 # Node not leader
1061 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001062 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001063 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001064 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001065 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001066 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001067 except TypeError:
1068 main.log.exception( self.name + ": Object not as expected" )
1069 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001070 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001071 main.log.error( self.name + ": EOF exception found" )
1072 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001073 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001074 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001075 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001076 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001077
kelvin-onlabd3b64892015-01-20 13:26:24 -08001078 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001079 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001080 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001081
Jon Hallefbd9792015-03-05 16:11:36 -08001082 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001083 partial mac address
1084
Jon Hall42db6dc2014-10-24 19:03:48 -04001085 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001086 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001087 try:
kelvin8ec71442015-01-15 16:57:00 -08001088 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001089 return None
1090 else:
1091 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001092 rawHosts = self.hosts()
1093 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001094 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001095 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001096 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001097 if not host:
1098 pass
1099 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001100 return host
1101 return None
Jon Hallc6793552016-01-19 14:18:37 -08001102 except ( TypeError, ValueError ):
1103 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001104 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001105 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001106 main.log.error( self.name + ": EOF exception found" )
1107 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001108 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001109 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001110 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001111 main.cleanAndExit()
Jon Hall42db6dc2014-10-24 19:03:48 -04001112
kelvin-onlabd3b64892015-01-20 13:26:24 -08001113 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001114 """
1115 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001116 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001117
andrewonlab3f0a4af2014-10-17 12:25:14 -04001118 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001119 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001120 IMPORTANT:
1121 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001122 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001123 Furthermore, it assumes that value of VLAN is '-1'
1124 Description:
kelvin8ec71442015-01-15 16:57:00 -08001125 Converts mininet hosts ( h1, h2, h3... ) into
1126 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1127 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001128 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001129 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001130
kelvin-onlabd3b64892015-01-20 13:26:24 -08001131 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001132 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001133 hostHex = hex( int( host ) ).zfill( 12 )
1134 hostHex = str( hostHex ).replace( 'x', '0' )
1135 i = iter( str( hostHex ) )
1136 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1137 hostHex = hostHex + "/-1"
1138 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001139
kelvin-onlabd3b64892015-01-20 13:26:24 -08001140 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001141
Jon Halld4d4b372015-01-28 16:02:41 -08001142 except TypeError:
1143 main.log.exception( self.name + ": Object not as expected" )
1144 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001145 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001146 main.log.error( self.name + ": EOF exception found" )
1147 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001148 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001149 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001150 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001151 main.cleanAndExit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001152
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001153 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001154 """
andrewonlabe6745342014-10-17 14:29:13 -04001155 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001156 * hostIdOne: ONOS host id for host1
1157 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001158 Optional:
1159 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001160 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001161 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001162 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001163 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001164 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001165 Returns:
1166 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001167 """
andrewonlabe6745342014-10-17 14:29:13 -04001168 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001169 cmdStr = "add-host-intent "
1170 if vlanId:
1171 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001172 if setVlan:
1173 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001174 if encap:
1175 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001176 if bandwidth:
1177 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001178 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001179 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001180 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001181 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001182 if re.search( "Error", handle ):
1183 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001184 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001185 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001186 else:
1187 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001188 str( hostIdOne ) + " and " + str( hostIdTwo ) )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001189 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001190 if match:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001191 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001192 else:
1193 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001194 main.log.debug( "Response from ONOS was: " +
1195 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001196 return None
Jon Hallc6793552016-01-19 14:18:37 -08001197 except AssertionError:
1198 main.log.exception( "" )
1199 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001200 except TypeError:
1201 main.log.exception( self.name + ": Object not as expected" )
1202 return None
andrewonlabe6745342014-10-17 14:29:13 -04001203 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001204 main.log.error( self.name + ": EOF exception found" )
1205 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001206 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001207 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001208 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001209 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04001210
kelvin-onlabd3b64892015-01-20 13:26:24 -08001211 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001212 """
andrewonlab7b31d232014-10-24 13:31:47 -04001213 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001214 * ingressDevice: device id of ingress device
1215 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001216 Optional:
1217 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001218 Description:
1219 Adds an optical intent by specifying an ingress and egress device
1220 Returns:
1221 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001222 """
andrewonlab7b31d232014-10-24 13:31:47 -04001223 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001224 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1225 " " + str( egressDevice )
1226 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001227 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001228 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001229 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001230 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001231 main.log.error( "Error in adding Optical intent" )
1232 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001233 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001234 main.log.info( "Optical intent installed between " +
1235 str( ingressDevice ) + " and " +
1236 str( egressDevice ) )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001237 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001238 if match:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001239 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001240 else:
1241 main.log.error( "Error, intent ID not found" )
1242 return None
Jon Hallc6793552016-01-19 14:18:37 -08001243 except AssertionError:
1244 main.log.exception( "" )
1245 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001246 except TypeError:
1247 main.log.exception( self.name + ": Object not as expected" )
1248 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001249 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001250 main.log.error( self.name + ": EOF exception found" )
1251 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001252 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001253 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001254 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001255 main.cleanAndExit()
andrewonlab7b31d232014-10-24 13:31:47 -04001256
kelvin-onlabd3b64892015-01-20 13:26:24 -08001257 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001258 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001259 ingressDevice,
1260 egressDevice,
1261 portIngress="",
1262 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001263 ethType="",
1264 ethSrc="",
1265 ethDst="",
1266 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001267 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001268 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001269 ipProto="",
1270 ipSrc="",
1271 ipDst="",
1272 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001273 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001274 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001275 setVlan="",
1276 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001277 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001278 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 * ingressDevice: device id of ingress device
1280 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001281 Optional:
1282 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001283 * ethSrc: specify ethSrc ( i.e. src mac addr )
1284 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001285 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001286 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001287 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001288 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001289 * ipSrc: specify ip source address
1290 * ipDst: specify ip destination address
1291 * tcpSrc: specify tcp source port
1292 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001293 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001294 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001295 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001296 Description:
kelvin8ec71442015-01-15 16:57:00 -08001297 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001298 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001299 Returns:
1300 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001301
Jon Halle3f39ff2015-01-13 11:50:53 -08001302 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001303 options developers provide for point-to-point
1304 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001305 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001306 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001307 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001308
Jeremy Songsterff553672016-05-12 17:06:23 -07001309 if ethType:
1310 cmd += " --ethType " + str( ethType )
1311 if ethSrc:
1312 cmd += " --ethSrc " + str( ethSrc )
1313 if ethDst:
1314 cmd += " --ethDst " + str( ethDst )
1315 if bandwidth:
1316 cmd += " --bandwidth " + str( bandwidth )
1317 if lambdaAlloc:
1318 cmd += " --lambda "
1319 if ipProto:
1320 cmd += " --ipProto " + str( ipProto )
1321 if ipSrc:
1322 cmd += " --ipSrc " + str( ipSrc )
1323 if ipDst:
1324 cmd += " --ipDst " + str( ipDst )
1325 if tcpSrc:
1326 cmd += " --tcpSrc " + str( tcpSrc )
1327 if tcpDst:
1328 cmd += " --tcpDst " + str( tcpDst )
1329 if vlanId:
1330 cmd += " -v " + str( vlanId )
1331 if setVlan:
1332 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001333 if encap:
1334 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001335 if protected:
1336 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001337
kelvin8ec71442015-01-15 16:57:00 -08001338 # Check whether the user appended the port
1339 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001340 if "/" in ingressDevice:
1341 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001342 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001343 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001344 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001345 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001346 # Would it make sense to throw an exception and exit
1347 # the test?
1348 return None
andrewonlab36af3822014-11-18 17:48:18 -05001349
kelvin8ec71442015-01-15 16:57:00 -08001350 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001351 str( ingressDevice ) + "/" +\
1352 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001353
kelvin-onlabd3b64892015-01-20 13:26:24 -08001354 if "/" in egressDevice:
1355 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001356 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001357 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001358 main.log.error( "You must specify the egress port" )
1359 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001360
kelvin8ec71442015-01-15 16:57:00 -08001361 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001362 str( egressDevice ) + "/" +\
1363 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001364
kelvin-onlab898a6c62015-01-16 14:13:53 -08001365 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001366 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001367 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001368 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001369 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001370 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001371 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001372 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001373 # TODO: print out all the options in this message?
1374 main.log.info( "Point-to-point intent installed between " +
1375 str( ingressDevice ) + " and " +
1376 str( egressDevice ) )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001377 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabfb521662015-02-27 09:52:40 -08001378 if match:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001379 return match.group()[ 3:-1 ]
kelvin-onlabfb521662015-02-27 09:52:40 -08001380 else:
1381 main.log.error( "Error, intent ID not found" )
1382 return None
Jon Hallc6793552016-01-19 14:18:37 -08001383 except AssertionError:
1384 main.log.exception( "" )
1385 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001386 except TypeError:
1387 main.log.exception( self.name + ": Object not as expected" )
1388 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001389 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001390 main.log.error( self.name + ": EOF exception found" )
1391 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001392 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001393 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001394 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001395 main.cleanAndExit()
andrewonlab4dbb4d82014-10-17 18:22:31 -04001396
kelvin-onlabd3b64892015-01-20 13:26:24 -08001397 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001398 self,
shahshreyac2f97072015-03-19 17:04:29 -07001399 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001400 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001401 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001402 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001403 ethType="",
1404 ethSrc="",
1405 ethDst="",
1406 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001407 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001408 ipProto="",
1409 ipSrc="",
1410 ipDst="",
1411 tcpSrc="",
1412 tcpDst="",
1413 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001414 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001415 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001416 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001417 partial=False,
1418 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001419 """
shahshreyad0c80432014-12-04 16:56:05 -08001420 Note:
shahshreya70622b12015-03-19 17:19:00 -07001421 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001422 is same. That is, all ingress devices include port numbers
1423 with a "/" or all ingress devices could specify device
1424 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001425 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001426 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001427 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001428 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001429 Optional:
1430 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001431 * ethSrc: specify ethSrc ( i.e. src mac addr )
1432 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001433 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001434 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001435 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001436 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001437 * ipSrc: specify ip source address
1438 * ipDst: specify ip destination address
1439 * tcpSrc: specify tcp source port
1440 * tcpDst: specify tcp destination port
1441 * setEthSrc: action to Rewrite Source MAC Address
1442 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001443 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001444 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001445 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001446 Description:
kelvin8ec71442015-01-15 16:57:00 -08001447 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001448 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001449 Returns:
1450 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001451
Jon Halle3f39ff2015-01-13 11:50:53 -08001452 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001453 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001454 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001455 """
shahshreyad0c80432014-12-04 16:56:05 -08001456 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001457 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001458
Jeremy Songsterff553672016-05-12 17:06:23 -07001459 if ethType:
1460 cmd += " --ethType " + str( ethType )
1461 if ethSrc:
1462 cmd += " --ethSrc " + str( ethSrc )
1463 if ethDst:
1464 cmd += " --ethDst " + str( ethDst )
1465 if bandwidth:
1466 cmd += " --bandwidth " + str( bandwidth )
1467 if lambdaAlloc:
1468 cmd += " --lambda "
1469 if ipProto:
1470 cmd += " --ipProto " + str( ipProto )
1471 if ipSrc:
1472 cmd += " --ipSrc " + str( ipSrc )
1473 if ipDst:
1474 cmd += " --ipDst " + str( ipDst )
1475 if tcpSrc:
1476 cmd += " --tcpSrc " + str( tcpSrc )
1477 if tcpDst:
1478 cmd += " --tcpDst " + str( tcpDst )
1479 if setEthSrc:
1480 cmd += " --setEthSrc " + str( setEthSrc )
1481 if setEthDst:
1482 cmd += " --setEthDst " + str( setEthDst )
1483 if vlanId:
1484 cmd += " -v " + str( vlanId )
1485 if setVlan:
1486 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001487 if partial:
1488 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001489 if encap:
1490 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001491
kelvin8ec71442015-01-15 16:57:00 -08001492 # Check whether the user appended the port
1493 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001494
1495 if portIngressList is None:
1496 for ingressDevice in ingressDeviceList:
1497 if "/" in ingressDevice:
1498 cmd += " " + str( ingressDevice )
1499 else:
1500 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001501 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001502 # TODO: perhaps more meaningful return
1503 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001504 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001505 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001506 for ingressDevice, portIngress in zip( ingressDeviceList,
1507 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001508 cmd += " " + \
1509 str( ingressDevice ) + "/" +\
1510 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001511 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001512 main.log.error( "Device list and port list does not " +
1513 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001514 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001515 if "/" in egressDevice:
1516 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001517 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001518 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001519 main.log.error( "You must specify " +
1520 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001521 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001522
kelvin8ec71442015-01-15 16:57:00 -08001523 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001524 str( egressDevice ) + "/" +\
1525 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001526 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001527 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001528 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001529 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001530 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001531 main.log.error( "Error in adding multipoint-to-singlepoint " +
1532 "intent" )
1533 return None
shahshreyad0c80432014-12-04 16:56:05 -08001534 else:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001535 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001536 if match:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001537 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001538 else:
1539 main.log.error( "Error, intent ID not found" )
1540 return None
Jon Hallc6793552016-01-19 14:18:37 -08001541 except AssertionError:
1542 main.log.exception( "" )
1543 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001544 except TypeError:
1545 main.log.exception( self.name + ": Object not as expected" )
1546 return None
1547 except pexpect.EOF:
1548 main.log.error( self.name + ": EOF exception found" )
1549 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001550 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001551 except Exception:
1552 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001553 main.cleanAndExit()
kelvin-onlabb9408212015-04-01 13:34:04 -07001554
1555 def addSinglepointToMultipointIntent(
1556 self,
1557 ingressDevice,
1558 egressDeviceList,
1559 portIngress="",
1560 portEgressList=None,
1561 ethType="",
1562 ethSrc="",
1563 ethDst="",
1564 bandwidth="",
1565 lambdaAlloc=False,
1566 ipProto="",
1567 ipSrc="",
1568 ipDst="",
1569 tcpSrc="",
1570 tcpDst="",
1571 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001572 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001573 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001574 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001575 partial=False,
1576 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001577 """
1578 Note:
1579 This function assumes the format of all egress devices
1580 is same. That is, all egress devices include port numbers
1581 with a "/" or all egress devices could specify device
1582 ids and port numbers seperately.
1583 Required:
1584 * EgressDeviceList: List of device ids of egress device
1585 ( Atleast 2 eress devices required in the list )
1586 * ingressDevice: device id of ingress device
1587 Optional:
1588 * ethType: specify ethType
1589 * ethSrc: specify ethSrc ( i.e. src mac addr )
1590 * ethDst: specify ethDst ( i.e. dst mac addr )
1591 * bandwidth: specify bandwidth capacity of link
1592 * lambdaAlloc: if True, intent will allocate lambda
1593 for the specified intent
1594 * ipProto: specify ip protocol
1595 * ipSrc: specify ip source address
1596 * ipDst: specify ip destination address
1597 * tcpSrc: specify tcp source port
1598 * tcpDst: specify tcp destination port
1599 * setEthSrc: action to Rewrite Source MAC Address
1600 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001601 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001602 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001603 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001604 Description:
1605 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1606 specifying device id's and optional fields
1607 Returns:
1608 A string of the intent id or None on error
1609
1610 NOTE: This function may change depending on the
1611 options developers provide for singlepoint-to-multipoint
1612 intent via cli
1613 """
1614 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001615 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001616
Jeremy Songsterff553672016-05-12 17:06:23 -07001617 if ethType:
1618 cmd += " --ethType " + str( ethType )
1619 if ethSrc:
1620 cmd += " --ethSrc " + str( ethSrc )
1621 if ethDst:
1622 cmd += " --ethDst " + str( ethDst )
1623 if bandwidth:
1624 cmd += " --bandwidth " + str( bandwidth )
1625 if lambdaAlloc:
1626 cmd += " --lambda "
1627 if ipProto:
1628 cmd += " --ipProto " + str( ipProto )
1629 if ipSrc:
1630 cmd += " --ipSrc " + str( ipSrc )
1631 if ipDst:
1632 cmd += " --ipDst " + str( ipDst )
1633 if tcpSrc:
1634 cmd += " --tcpSrc " + str( tcpSrc )
1635 if tcpDst:
1636 cmd += " --tcpDst " + str( tcpDst )
1637 if setEthSrc:
1638 cmd += " --setEthSrc " + str( setEthSrc )
1639 if setEthDst:
1640 cmd += " --setEthDst " + str( setEthDst )
1641 if vlanId:
1642 cmd += " -v " + str( vlanId )
1643 if setVlan:
1644 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001645 if partial:
1646 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001647 if encap:
1648 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001649
1650 # Check whether the user appended the port
1651 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001652
kelvin-onlabb9408212015-04-01 13:34:04 -07001653 if "/" in ingressDevice:
1654 cmd += " " + str( ingressDevice )
1655 else:
1656 if not portIngress:
1657 main.log.error( "You must specify " +
1658 "the Ingress port" )
1659 return main.FALSE
1660
1661 cmd += " " +\
1662 str( ingressDevice ) + "/" +\
1663 str( portIngress )
1664
1665 if portEgressList is None:
1666 for egressDevice in egressDeviceList:
1667 if "/" in egressDevice:
1668 cmd += " " + str( egressDevice )
1669 else:
1670 main.log.error( "You must specify " +
1671 "the egress port" )
1672 # TODO: perhaps more meaningful return
1673 return main.FALSE
1674 else:
1675 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001676 for egressDevice, portEgress in zip( egressDeviceList,
1677 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001678 cmd += " " + \
1679 str( egressDevice ) + "/" +\
1680 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001681 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001682 main.log.error( "Device list and port list does not " +
1683 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001684 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001685 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001686 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001687 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001688 # If error, return error message
1689 if re.search( "Error", handle ):
1690 main.log.error( "Error in adding singlepoint-to-multipoint " +
1691 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001692 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001693 else:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001694 match = re.search( 'id=0x([\da-f]+),', handle )
kelvin-onlabb9408212015-04-01 13:34:04 -07001695 if match:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001696 return match.group()[ 3:-1 ]
kelvin-onlabb9408212015-04-01 13:34:04 -07001697 else:
1698 main.log.error( "Error, intent ID not found" )
1699 return None
Jon Hallc6793552016-01-19 14:18:37 -08001700 except AssertionError:
1701 main.log.exception( "" )
1702 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001703 except TypeError:
1704 main.log.exception( self.name + ": Object not as expected" )
1705 return None
shahshreyad0c80432014-12-04 16:56:05 -08001706 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001707 main.log.error( self.name + ": EOF exception found" )
1708 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001709 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001710 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001711 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001712 main.cleanAndExit()
shahshreyad0c80432014-12-04 16:56:05 -08001713
Hari Krishna9e232602015-04-13 17:29:08 -07001714 def addMplsIntent(
1715 self,
1716 ingressDevice,
1717 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001718 ingressPort="",
1719 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001720 ethType="",
1721 ethSrc="",
1722 ethDst="",
1723 bandwidth="",
1724 lambdaAlloc=False,
1725 ipProto="",
1726 ipSrc="",
1727 ipDst="",
1728 tcpSrc="",
1729 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001730 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001731 egressLabel="",
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001732 priority="" ):
Hari Krishna9e232602015-04-13 17:29:08 -07001733 """
1734 Required:
1735 * ingressDevice: device id of ingress device
1736 * egressDevice: device id of egress device
1737 Optional:
1738 * ethType: specify ethType
1739 * ethSrc: specify ethSrc ( i.e. src mac addr )
1740 * ethDst: specify ethDst ( i.e. dst mac addr )
1741 * bandwidth: specify bandwidth capacity of link
1742 * lambdaAlloc: if True, intent will allocate lambda
1743 for the specified intent
1744 * ipProto: specify ip protocol
1745 * ipSrc: specify ip source address
1746 * ipDst: specify ip destination address
1747 * tcpSrc: specify tcp source port
1748 * tcpDst: specify tcp destination port
1749 * ingressLabel: Ingress MPLS label
1750 * egressLabel: Egress MPLS label
1751 Description:
1752 Adds MPLS intent by
1753 specifying device id's and optional fields
1754 Returns:
1755 A string of the intent id or None on error
1756
1757 NOTE: This function may change depending on the
1758 options developers provide for MPLS
1759 intent via cli
1760 """
1761 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001762 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001763
Jeremy Songsterff553672016-05-12 17:06:23 -07001764 if ethType:
1765 cmd += " --ethType " + str( ethType )
1766 if ethSrc:
1767 cmd += " --ethSrc " + str( ethSrc )
1768 if ethDst:
1769 cmd += " --ethDst " + str( ethDst )
1770 if bandwidth:
1771 cmd += " --bandwidth " + str( bandwidth )
1772 if lambdaAlloc:
1773 cmd += " --lambda "
1774 if ipProto:
1775 cmd += " --ipProto " + str( ipProto )
1776 if ipSrc:
1777 cmd += " --ipSrc " + str( ipSrc )
1778 if ipDst:
1779 cmd += " --ipDst " + str( ipDst )
1780 if tcpSrc:
1781 cmd += " --tcpSrc " + str( tcpSrc )
1782 if tcpDst:
1783 cmd += " --tcpDst " + str( tcpDst )
1784 if ingressLabel:
1785 cmd += " --ingressLabel " + str( ingressLabel )
1786 if egressLabel:
1787 cmd += " --egressLabel " + str( egressLabel )
1788 if priority:
1789 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001790
1791 # Check whether the user appended the port
1792 # or provided it as an input
1793 if "/" in ingressDevice:
1794 cmd += " " + str( ingressDevice )
1795 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001796 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001797 main.log.error( "You must specify the ingress port" )
1798 return None
1799
1800 cmd += " " + \
1801 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001802 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001803
1804 if "/" in egressDevice:
1805 cmd += " " + str( egressDevice )
1806 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001807 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001808 main.log.error( "You must specify the egress port" )
1809 return None
1810
1811 cmd += " " +\
1812 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001813 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001814
1815 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001816 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001817 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001818 # If error, return error message
1819 if re.search( "Error", handle ):
1820 main.log.error( "Error in adding mpls intent" )
1821 return None
1822 else:
1823 # TODO: print out all the options in this message?
1824 main.log.info( "MPLS intent installed between " +
1825 str( ingressDevice ) + " and " +
1826 str( egressDevice ) )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001827 match = re.search( 'id=0x([\da-f]+),', handle )
Hari Krishna9e232602015-04-13 17:29:08 -07001828 if match:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07001829 return match.group()[ 3:-1 ]
Hari Krishna9e232602015-04-13 17:29:08 -07001830 else:
1831 main.log.error( "Error, intent ID not found" )
1832 return None
Jon Hallc6793552016-01-19 14:18:37 -08001833 except AssertionError:
1834 main.log.exception( "" )
1835 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001836 except TypeError:
1837 main.log.exception( self.name + ": Object not as expected" )
1838 return None
1839 except pexpect.EOF:
1840 main.log.error( self.name + ": EOF exception found" )
1841 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001842 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001843 except Exception:
1844 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001845 main.cleanAndExit()
Hari Krishna9e232602015-04-13 17:29:08 -07001846
Jon Hallefbd9792015-03-05 16:11:36 -08001847 def removeIntent( self, intentId, app='org.onosproject.cli',
1848 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001849 """
shahshreya1c818fc2015-02-26 13:44:08 -08001850 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001851 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001852 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001853 -p or --purge: Purge the intent from the store after removal
1854
Jon Halle3f39ff2015-01-13 11:50:53 -08001855 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001856 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001857 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001858 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001859 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001860 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001861 if purge:
1862 cmdStr += " -p"
1863 if sync:
1864 cmdStr += " -s"
1865
1866 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001867 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001868 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001869 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001870 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001871 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001872 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001873 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001874 # TODO: Should this be main.TRUE
1875 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001876 except AssertionError:
1877 main.log.exception( "" )
1878 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001879 except TypeError:
1880 main.log.exception( self.name + ": Object not as expected" )
1881 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001882 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001883 main.log.error( self.name + ": EOF exception found" )
1884 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001885 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001886 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001887 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001888 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04001889
YPZhangfebf7302016-05-24 16:45:56 -07001890 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001891 """
1892 Description:
1893 Remove all the intents
1894 Optional args:-
1895 -s or --sync: Waits for the removal before returning
1896 -p or --purge: Purge the intent from the store after removal
1897 Returns:
1898 Returns main.TRUE if all intents are removed, otherwise returns
1899 main.FALSE; Returns None for exception
1900 """
1901 try:
1902 cmdStr = "remove-intent"
1903 if purge:
1904 cmdStr += " -p"
1905 if sync:
1906 cmdStr += " -s"
1907
1908 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001909 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001910 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08001911 assert "Command not found:" not in handle, handle
1912 if re.search( "Error", handle ):
1913 main.log.error( "Error in removing intent" )
1914 return main.FALSE
1915 else:
1916 return main.TRUE
1917 except AssertionError:
1918 main.log.exception( "" )
1919 return None
1920 except TypeError:
1921 main.log.exception( self.name + ": Object not as expected" )
1922 return None
1923 except pexpect.EOF:
1924 main.log.error( self.name + ": EOF exception found" )
1925 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001926 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001927 except Exception:
1928 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001929 main.cleanAndExit()
Jeremy42df2e72016-02-23 16:37:46 -08001930
Hari Krishnaacabd5a2015-07-01 17:10:19 -07001931 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07001932 """
1933 Purges all WITHDRAWN Intents
1934 """
1935 try:
1936 cmdStr = "purge-intents"
1937 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001938 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001939 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07001940 if re.search( "Error", handle ):
1941 main.log.error( "Error in purging intents" )
1942 return main.FALSE
1943 else:
1944 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001945 except AssertionError:
1946 main.log.exception( "" )
1947 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07001948 except TypeError:
1949 main.log.exception( self.name + ": Object not as expected" )
1950 return None
1951 except pexpect.EOF:
1952 main.log.error( self.name + ": EOF exception found" )
1953 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001954 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07001955 except Exception:
1956 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001957 main.cleanAndExit()
Hari Krishna0ce0e152015-06-23 09:55:29 -07001958
kelvin-onlabd3b64892015-01-20 13:26:24 -08001959 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08001960 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08001961 NOTE: This method should be used after installing application:
1962 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08001963 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001964 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08001965 Description:
1966 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08001967 """
pingping-lin8b306ac2014-11-17 18:13:51 -08001968 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001969 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001970 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001971 cmdStr += " -j"
1972 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001973 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001974 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08001975 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001976 except AssertionError:
1977 main.log.exception( "" )
1978 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001979 except TypeError:
1980 main.log.exception( self.name + ": Object not as expected" )
1981 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08001982 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001983 main.log.error( self.name + ": EOF exception found" )
1984 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07001985 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001986 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001987 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07001988 main.cleanAndExit()
pingping-lin8b306ac2014-11-17 18:13:51 -08001989
pingping-lin54b03372015-08-13 14:43:10 -07001990 def ipv4RouteNumber( self ):
1991 """
1992 NOTE: This method should be used after installing application:
1993 onos-app-sdnip
1994 Description:
1995 Obtain the total IPv4 routes number in the system
1996 """
1997 try:
Pratik Parab57963572017-05-09 11:37:54 -07001998 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07001999 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002000 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002001 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002002 jsonResult = json.loads( handle )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002003 return len( jsonResult[ 'routes4' ] )
Jon Hallc6793552016-01-19 14:18:37 -08002004 except AssertionError:
2005 main.log.exception( "" )
2006 return None
2007 except ( TypeError, ValueError ):
2008 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002009 return None
2010 except pexpect.EOF:
2011 main.log.error( self.name + ": EOF exception found" )
2012 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002013 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002014 except Exception:
2015 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002016 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002017
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002018 # =============Function to check Bandwidth allocation========
2019 def allocations( self, jsonFormat=True, dollarSign=True ):
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002020 """
2021 Description:
2022 Obtain Bandwidth Allocation Information from ONOS cli.
2023 """
2024 try:
2025 cmdStr = "allocations"
2026 if jsonFormat:
2027 cmdStr += " -j"
2028 handle = self.sendline( cmdStr, timeout=300, dollarSign=True )
2029 assert handle is not None, "Error in sendline"
2030 assert "Command not found:" not in handle, handle
2031 return handle
2032 except AssertionError:
2033 main.log.exception( "" )
2034 return None
2035 except ( TypeError, ValueError ):
2036 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2037 return None
2038 except pexpect.EOF:
2039 main.log.error( self.name + ": EOF exception found" )
2040 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002041 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002042 except Exception:
2043 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002044 main.cleanAndExit()
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002045
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002046 def intents( self, jsonFormat=True, summary=False, **intentargs ):
kelvin8ec71442015-01-15 16:57:00 -08002047 """
andrewonlabe6745342014-10-17 14:29:13 -04002048 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002049 Obtain intents from the ONOS cli.
2050 Optional:
2051 * jsonFormat: Enable output formatting in json, default to True
2052 * summary: Whether only output the intent summary, defaults to False
2053 * type: Only output a certain type of intent. This options is valid
2054 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002055 """
andrewonlabe6745342014-10-17 14:29:13 -04002056 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002057 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002058 if summary:
2059 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002060 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002061 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002062 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002063 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002064 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002065 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002066 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002067 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002068 else:
Jon Hallff566d52016-01-15 14:45:36 -08002069 intentType = ""
2070 # IF we want the summary of a specific intent type
2071 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002072 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002073 if intentType in jsonResult.keys():
2074 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002075 else:
Jon Hallff566d52016-01-15 14:45:36 -08002076 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002077 return handle
2078 else:
2079 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002080 except AssertionError:
2081 main.log.exception( "" )
2082 return None
2083 except ( TypeError, ValueError ):
2084 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002085 return None
2086 except pexpect.EOF:
2087 main.log.error( self.name + ": EOF exception found" )
2088 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002089 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002090 except Exception:
2091 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002092 main.cleanAndExit()
pingping-lin54b03372015-08-13 14:43:10 -07002093
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002094 def getIntentState( self, intentsId, intentsJson=None ):
kelvin-onlab54400a92015-02-26 18:05:51 -08002095 """
You Wangfdcbfc42016-05-16 12:16:53 -07002096 Description:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002097 Gets intent state. Accepts a single intent ID ( string type ) or a
You Wangfdcbfc42016-05-16 12:16:53 -07002098 list of intent IDs.
2099 Parameters:
2100 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002101 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002102 Returns:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002103 Returns the state ( string type ) of the ID if a single intent ID is
You Wangfdcbfc42016-05-16 12:16:53 -07002104 accepted.
2105 Returns a list of dictionaries if a list of intent IDs is accepted,
2106 and each dictionary maps 'id' to the Intent ID and 'state' to
2107 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002108 """
kelvin-onlab54400a92015-02-26 18:05:51 -08002109 try:
2110 state = "State is Undefined"
2111 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002112 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002113 else:
Jon Hallc6793552016-01-19 14:18:37 -08002114 rawJson = intentsJson
2115 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002116 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002117 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002118 if intentsId == intent[ 'id' ]:
2119 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002120 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002121 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002122 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002123 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002124 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002125 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002126 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002127 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002128 for intent in parsedIntentsJson:
2129 if intentsId[ i ] == intent[ 'id' ]:
2130 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002131 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002132 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002133 break
Jon Hallefbd9792015-03-05 16:11:36 -08002134 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002135 main.log.warn( "Could not find all intents in ONOS output" )
2136 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002137 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002138 else:
Jon Hall53158082017-05-18 11:17:00 -07002139 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002140 return None
Jon Hallc6793552016-01-19 14:18:37 -08002141 except ( TypeError, ValueError ):
2142 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002143 return None
2144 except pexpect.EOF:
2145 main.log.error( self.name + ": EOF exception found" )
2146 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002147 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002148 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002149 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002150 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07002151
Jon Hallf539eb92017-05-22 17:18:42 -07002152 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002153 """
2154 Description:
2155 Check intents state
2156 Required:
2157 intentsId - List of intents ID to be checked
2158 Optional:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002159 expectedState - Check the expected state( s ) of each intents
kelvin-onlabf512e942015-06-08 19:42:59 -07002160 state in the list.
2161 *NOTE: You can pass in a list of expected state,
2162 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002163 Return:
Jon Hall53158082017-05-18 11:17:00 -07002164 Returns main.TRUE only if all intent are the same as expected states,
2165 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002166 """
2167 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002168 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002169 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002170
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002171 # intentsDict = self.getIntentState( intentsId )
Devin Lim752dd7b2017-06-27 14:40:03 -07002172 intentsDict = []
2173 for intent in json.loads( self.intents() ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002174 if isinstance( intentsId, types.StringType ) \
2175 and intent.get( 'id' ) == intentsId:
2176 intentsDict.append( intent )
2177 elif isinstance( intentsId, types.ListType ) \
Devin Lim752dd7b2017-06-27 14:40:03 -07002178 and any( intent.get( 'id' ) == ids for ids in intentsId ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002179 intentsDict.append( intent )
Devin Lim752dd7b2017-06-27 14:40:03 -07002180
2181 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002182 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002183 "getting intents state" )
2184 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002185
2186 if isinstance( expectedState, types.StringType ):
2187 for intents in intentsDict:
2188 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002189 main.log.debug( self.name + " : Intent ID - " +
2190 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002191 " actual state = " +
2192 intents.get( 'state' )
2193 + " does not equal expected state = "
2194 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002195 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002196 elif isinstance( expectedState, types.ListType ):
2197 for intents in intentsDict:
2198 if not any( state == intents.get( 'state' ) for state in
2199 expectedState ):
2200 main.log.debug( self.name + " : Intent ID - " +
2201 intents.get( 'id' ) +
2202 " actual state = " +
2203 intents.get( 'state' ) +
2204 " does not equal expected states = "
2205 + str( expectedState ) )
2206 returnValue = main.FALSE
2207
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002208 if returnValue == main.TRUE:
2209 main.log.info( self.name + ": All " +
2210 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002211 " intents are in " + str( expectedState ) +
2212 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002213 return returnValue
2214 except TypeError:
2215 main.log.exception( self.name + ": Object not as expected" )
2216 return None
2217 except pexpect.EOF:
2218 main.log.error( self.name + ": EOF exception found" )
2219 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002220 main.cleanAndExit()
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002221 except Exception:
2222 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002223 main.cleanAndExit()
andrewonlabe6745342014-10-17 14:29:13 -04002224
Jon Hallf539eb92017-05-22 17:18:42 -07002225 def compareBandwidthAllocations( self, expectedAllocations ):
2226 """
2227 Description:
2228 Compare the allocated bandwidth with the given allocations
2229 Required:
2230 expectedAllocations - The expected ONOS output of the allocations command
2231 Return:
2232 Returns main.TRUE only if all intent are the same as expected states,
2233 otherwise returns main.FALSE.
2234 """
2235 # FIXME: Convert these string comparisons to object comparisons
2236 try:
2237 returnValue = main.TRUE
2238 bandwidthFailed = False
2239 rawAlloc = self.allocations()
2240 expectedFormat = StringIO( expectedAllocations )
2241 ONOSOutput = StringIO( rawAlloc )
2242 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2243 str( expectedFormat ) ) )
2244
2245 for actual, expected in izip( ONOSOutput, expectedFormat ):
2246 actual = actual.rstrip()
2247 expected = expected.rstrip()
2248 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2249 if actual != expected and 'allocated' in actual and 'allocated' in expected:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002250 marker1 = actual.find( 'allocated' )
2251 m1 = actual[ :marker1 ]
2252 marker2 = expected.find( 'allocated' )
2253 m2 = expected[ :marker2 ]
Jon Hallf539eb92017-05-22 17:18:42 -07002254 if m1 != m2:
2255 bandwidthFailed = True
2256 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2257 bandwidthFailed = True
2258 expectedFormat.close()
2259 ONOSOutput.close()
2260
2261 if bandwidthFailed:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002262 main.log.error( "Bandwidth not allocated correctly using Intents!!" )
Jon Hallf539eb92017-05-22 17:18:42 -07002263 returnValue = main.FALSE
2264 return returnValue
2265 except TypeError:
2266 main.log.exception( self.name + ": Object not as expected" )
2267 return None
2268 except pexpect.EOF:
2269 main.log.error( self.name + ": EOF exception found" )
2270 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002271 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002272 except Exception:
2273 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002274 main.cleanAndExit()
Jon Hallf539eb92017-05-22 17:18:42 -07002275
You Wang66518af2016-05-16 15:32:59 -07002276 def compareIntent( self, intentDict ):
2277 """
2278 Description:
2279 Compare the intent ids and states provided in the argument with all intents in ONOS
2280 Return:
2281 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2282 Arguments:
2283 intentDict: a dictionary which maps intent ids to intent states
2284 """
2285 try:
2286 intentsRaw = self.intents()
2287 intentsJson = json.loads( intentsRaw )
2288 intentDictONOS = {}
2289 for intent in intentsJson:
2290 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002291 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002292 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002293 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002294 str( len( intentDict ) ) + " expected and " +
2295 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002296 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002297 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002298 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002299 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2300 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002301 else:
2302 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2303 main.log.debug( self.name + ": intent ID - " + intentID +
2304 " expected state is " + intentDict[ intentID ] +
2305 " but actual state is " + intentDictONOS[ intentID ] )
2306 returnValue = main.FALSE
2307 intentDictONOS.pop( intentID )
2308 if len( intentDictONOS ) > 0:
2309 returnValue = main.FALSE
2310 for intentID in intentDictONOS.keys():
2311 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002312 if returnValue == main.TRUE:
2313 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2314 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002315 except KeyError:
2316 main.log.exception( self.name + ": KeyError exception found" )
2317 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002318 except ( TypeError, ValueError ):
2319 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002320 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002321 except pexpect.EOF:
2322 main.log.error( self.name + ": EOF exception found" )
2323 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002324 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002325 except Exception:
2326 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002327 main.cleanAndExit()
You Wang66518af2016-05-16 15:32:59 -07002328
YPZhang14a4aa92016-07-15 13:37:15 -07002329 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002330 """
2331 Description:
2332 Check the number of installed intents.
2333 Optional:
2334 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002335 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002336 Return:
2337 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2338 , otherwise, returns main.FALSE.
2339 """
GlennRCed771242016-01-13 17:02:47 -08002340 try:
2341 cmd = "intents -s -j"
2342
2343 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002344 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002345 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002346 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002347 response = json.loads( response )
2348
2349 # get total and installed number, see if they are match
2350 allState = response.get( 'all' )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002351 if allState.get( 'total' ) == allState.get( 'installed' ):
2352 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002353 return main.TRUE
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002354 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get( 'total' ), allState.get( 'installed' ) ) )
GlennRCed771242016-01-13 17:02:47 -08002355 return main.FALSE
2356
Jon Hallc6793552016-01-19 14:18:37 -08002357 except ( TypeError, ValueError ):
2358 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002359 return None
2360 except pexpect.EOF:
2361 main.log.error( self.name + ": EOF exception found" )
2362 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002363 if noExit:
2364 return main.FALSE
2365 else:
Devin Lim44075962017-08-11 10:56:37 -07002366 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07002367 except pexpect.TIMEOUT:
2368 main.log.error( self.name + ": ONOS timeout" )
2369 return None
GlennRCed771242016-01-13 17:02:47 -08002370 except Exception:
2371 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002372 if noExit:
2373 return main.FALSE
2374 else:
Devin Lim44075962017-08-11 10:56:37 -07002375 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002376
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002377 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002378 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002379 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002380 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002381 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002382 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002383 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002384 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002385 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002386 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002387 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002388 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002389 if noCore:
2390 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002391 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002392 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002393 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002394 assert "Command not found:" not in handle, handle
2395 if re.search( "Error:", handle ):
2396 main.log.error( self.name + ": flows() response: " +
2397 str( handle ) )
2398 return handle
2399 except AssertionError:
2400 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002401 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002402 except TypeError:
2403 main.log.exception( self.name + ": Object not as expected" )
2404 return None
Jon Hallc6793552016-01-19 14:18:37 -08002405 except pexpect.TIMEOUT:
2406 main.log.error( self.name + ": ONOS timeout" )
2407 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002408 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002409 main.log.error( self.name + ": EOF exception found" )
2410 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002411 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002412 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002413 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002414 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002415
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002416 def checkFlowCount( self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002417 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002418 count = int( count ) if count else 0
2419 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002420
Jon Halle0f0b342017-04-18 11:43:47 -07002421 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002422 """
2423 Description:
GlennRCed771242016-01-13 17:02:47 -08002424 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002425 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2426 if the count of those states is 0, which means all current flows
2427 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002428 Optional:
GlennRCed771242016-01-13 17:02:47 -08002429 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002430 Return:
2431 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002432 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002433 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002434 """
2435 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002436 states = [ "PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED" ]
GlennRCed771242016-01-13 17:02:47 -08002437 checkedStates = []
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002438 statesCount = [ 0, 0, 0, 0 ]
GlennRCed771242016-01-13 17:02:47 -08002439 for s in states:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002440 rawFlows = self.flows( state=s, timeout=timeout )
YPZhang240842b2016-05-17 12:00:50 -07002441 if rawFlows:
2442 # if we didn't get flows or flows function return None, we should return
2443 # main.Flase
2444 checkedStates.append( json.loads( rawFlows ) )
2445 else:
2446 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002447 for i in range( len( states ) ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002448 for c in checkedStates[ i ]:
Jon Hallc6793552016-01-19 14:18:37 -08002449 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002450 statesCount[ i ] += int( c.get( "flowCount" ) )
Jon Hallc6793552016-01-19 14:18:37 -08002451 except TypeError:
2452 main.log.exception( "Json object not as expected" )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002453 main.log.info( states[ i ] + " flows: " + str( statesCount[ i ] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002454
GlennRCed771242016-01-13 17:02:47 -08002455 # We want to count PENDING_ADD if isPENDING is true
2456 if isPENDING:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002457 if statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002458 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002459 else:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002460 if statesCount[ 0 ] + statesCount[ 1 ] + statesCount[ 2 ] + statesCount[ 3 ] > 0:
GlennRCed771242016-01-13 17:02:47 -08002461 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002462 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002463 except ( TypeError, ValueError ):
2464 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002465 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002466
YPZhang240842b2016-05-17 12:00:50 -07002467 except AssertionError:
2468 main.log.exception( "" )
2469 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002470 except pexpect.TIMEOUT:
2471 main.log.error( self.name + ": ONOS timeout" )
2472 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002473 except pexpect.EOF:
2474 main.log.error( self.name + ": EOF exception found" )
2475 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002476 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002477 except Exception:
2478 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002479 main.cleanAndExit()
kelvin-onlab4df89f22015-04-13 18:10:23 -07002480
GlennRCed771242016-01-13 17:02:47 -08002481 def pushTestIntents( self, ingress, egress, batchSize, offset="",
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002482 options="", timeout=10, background=False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002483 """
andrewonlab87852b02014-11-19 18:44:19 -05002484 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002485 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002486 a specific point-to-point intent definition
2487 Required:
GlennRCed771242016-01-13 17:02:47 -08002488 * ingress: specify source dpid
2489 * egress: specify destination dpid
2490 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002491 Optional:
GlennRCed771242016-01-13 17:02:47 -08002492 * offset: the keyOffset is where the next batch of intents
2493 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002494 * noExit: If set to True, TestON will not exit if any error when issus command
2495 * getResponse: If set to True, function will return ONOS response.
2496
GlennRCed771242016-01-13 17:02:47 -08002497 Returns: If failed to push test intents, it will returen None,
2498 if successful, return true.
2499 Timeout expection will return None,
2500 TypeError will return false
2501 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002502 """
andrewonlab87852b02014-11-19 18:44:19 -05002503 try:
GlennRCed771242016-01-13 17:02:47 -08002504 if background:
2505 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002506 else:
GlennRCed771242016-01-13 17:02:47 -08002507 back = ""
2508 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002509 ingress,
2510 egress,
2511 batchSize,
2512 offset,
2513 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002514 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002515 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002516 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002517 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002518 if getResponse:
2519 return response
2520
GlennRCed771242016-01-13 17:02:47 -08002521 # TODO: We should handle if there is failure in installation
2522 return main.TRUE
2523
Jon Hallc6793552016-01-19 14:18:37 -08002524 except AssertionError:
2525 main.log.exception( "" )
2526 return None
GlennRCed771242016-01-13 17:02:47 -08002527 except pexpect.TIMEOUT:
2528 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002529 return None
andrewonlab87852b02014-11-19 18:44:19 -05002530 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002531 main.log.error( self.name + ": EOF exception found" )
2532 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002533 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08002534 except TypeError:
2535 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002536 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002537 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002538 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002539 main.cleanAndExit()
andrewonlab87852b02014-11-19 18:44:19 -05002540
YPZhangebf9eb52016-05-12 15:20:24 -07002541 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002542 """
2543 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002544 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002545 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002546 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002547 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002548 """
2549 try:
YPZhange3109a72016-02-02 11:25:37 -08002550 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002551 cmd = "flows -c added"
2552 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2553 if rawFlows:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002554 rawFlows = rawFlows.split( "\n" )
YPZhange3109a72016-02-02 11:25:37 -08002555 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002556 for l in rawFlows:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002557 totalFlows += int( l.split( "Count=" )[ 1 ] )
YPZhang14a4aa92016-07-15 13:37:15 -07002558 else:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002559 main.log.error( "Response not as expected!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002560 return None
2561 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002562
You Wangd3cb2ce2016-05-16 14:01:24 -07002563 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002564 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002565 return None
2566 except pexpect.EOF:
2567 main.log.error( self.name + ": EOF exception found" )
2568 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002569 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002570 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002571 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002572 except pexpect.TIMEOUT:
2573 main.log.error( self.name + ": ONOS timeout" )
2574 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002575 except Exception:
2576 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002577 if not noExit:
Devin Lim44075962017-08-11 10:56:37 -07002578 main.cleanAndExit()
YPZhang14a4aa92016-07-15 13:37:15 -07002579 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002580
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002581 def getTotalIntentsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002582 """
2583 Description:
2584 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002585 Optional:
2586 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002587 Return:
2588 The number of intents
2589 """
2590 try:
2591 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002592 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002593 if response is None:
2594 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002595 response = json.loads( response )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002596 return int( response.get( "intents" ) )
You Wangd3cb2ce2016-05-16 14:01:24 -07002597 except ( TypeError, ValueError ):
2598 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002599 return None
2600 except pexpect.EOF:
2601 main.log.error( self.name + ": EOF exception found" )
2602 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002603 if noExit:
2604 return -1
2605 else:
Devin Lim44075962017-08-11 10:56:37 -07002606 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002607 except Exception:
2608 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002609 if noExit:
2610 return -1
2611 else:
Devin Lim44075962017-08-11 10:56:37 -07002612 main.cleanAndExit()
YPZhangb5d3f832016-01-23 22:54:26 -08002613
kelvin-onlabd3b64892015-01-20 13:26:24 -08002614 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002615 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002616 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002617 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002618 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002619 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002620 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002621 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002622 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002623 cmdStr += " -j"
2624 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002625 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002626 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002627 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002628 except AssertionError:
2629 main.log.exception( "" )
2630 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002631 except TypeError:
2632 main.log.exception( self.name + ": Object not as expected" )
2633 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002634 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002635 main.log.error( self.name + ": EOF exception found" )
2636 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002637 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002638 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002639 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002640 main.cleanAndExit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002641
kelvin-onlabd3b64892015-01-20 13:26:24 -08002642 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002643 """
2644 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002645 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002646 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002647 """
andrewonlab867212a2014-10-22 20:13:38 -04002648 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002649 cmdStr = "topology-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
jenkins7ead5a82015-03-13 10:28:21 -07002655 if handle:
2656 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002657 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002658 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002659 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002660 else:
2661 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002662 except AssertionError:
2663 main.log.exception( "" )
2664 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002665 except TypeError:
2666 main.log.exception( self.name + ": Object not as expected" )
2667 return None
andrewonlab867212a2014-10-22 20:13:38 -04002668 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002669 main.log.error( self.name + ": EOF exception found" )
2670 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002671 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002672 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002673 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002674 main.cleanAndExit()
andrewonlab867212a2014-10-22 20:13:38 -04002675
kelvin8ec71442015-01-15 16:57:00 -08002676 # Wrapper functions ****************
2677 # Wrapper functions use existing driver
2678 # functions and extends their use case.
2679 # For example, we may use the output of
2680 # a normal driver function, and parse it
2681 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002682
kelvin-onlabd3b64892015-01-20 13:26:24 -08002683 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002684 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002685 Description:
2686 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002687 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002688 try:
kelvin8ec71442015-01-15 16:57:00 -08002689 # Obtain output of intents function
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002690 intentsStr = self.intents( jsonFormat=True )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002691 if intentsStr is None:
2692 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002693 # Convert to a dictionary
2694 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002695 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002696 for intent in intents:
2697 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002698 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002699 except TypeError:
2700 main.log.exception( self.name + ": Object not as expected" )
2701 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002702 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002703 main.log.error( self.name + ": EOF exception found" )
2704 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002705 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002706 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002707 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002708 main.cleanAndExit()
andrewonlab9a50dfe2014-10-17 17:22:31 -04002709
You Wang3c276252016-09-21 15:21:36 -07002710 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002711 """
2712 Determine the number of flow rules for the given device id that are
2713 in the added state
You Wang3c276252016-09-21 15:21:36 -07002714 Params:
2715 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002716 """
2717 try:
You Wang3c276252016-09-21 15:21:36 -07002718 if core:
2719 cmdStr = "flows any " + str( deviceId ) + " | " +\
2720 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2721 else:
2722 cmdStr = "flows any " + str( deviceId ) + " | " +\
2723 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002724 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002725 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002726 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002727 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002728 except AssertionError:
2729 main.log.exception( "" )
2730 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002731 except pexpect.EOF:
2732 main.log.error( self.name + ": EOF exception found" )
2733 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002734 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002735 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002736 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002737 main.cleanAndExit()
andrewonlab95ce8322014-10-13 14:12:04 -04002738
kelvin-onlabd3b64892015-01-20 13:26:24 -08002739 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002740 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002741 Use 'devices' function to obtain list of all devices
2742 and parse the result to obtain a list of all device
2743 id's. Returns this list. Returns empty list if no
2744 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002745 List is ordered sequentially
2746
andrewonlab3e15ead2014-10-15 14:21:34 -04002747 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002748 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002749 the ids. By obtaining the list of device ids on the fly,
2750 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002751 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002752 try:
kelvin8ec71442015-01-15 16:57:00 -08002753 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002754 devicesStr = self.devices( jsonFormat=False )
2755 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002756
kelvin-onlabd3b64892015-01-20 13:26:24 -08002757 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002758 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002759 return idList
kelvin8ec71442015-01-15 16:57:00 -08002760
2761 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002762 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002763 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002764 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002765 # Split list further into arguments before and after string
2766 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002767 # append to idList
2768 for arg in tempList:
2769 idList.append( arg.split( "id=" )[ 1 ] )
2770 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002771
Jon Halld4d4b372015-01-28 16:02:41 -08002772 except TypeError:
2773 main.log.exception( self.name + ": Object not as expected" )
2774 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002775 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002776 main.log.error( self.name + ": EOF exception found" )
2777 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002778 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002779 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002780 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002781 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002782
kelvin-onlabd3b64892015-01-20 13:26:24 -08002783 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002784 """
andrewonlab7c211572014-10-15 16:45:20 -04002785 Uses 'nodes' function to obtain list of all nodes
2786 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002787 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002788 Returns:
2789 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002790 """
andrewonlab7c211572014-10-15 16:45:20 -04002791 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002792 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002793 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002794 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002795 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002796 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002797 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002798 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002799 nodesJson = json.loads( nodesStr )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002800 idList = [ node.get( 'id' ) for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002801 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002802 except ( TypeError, ValueError ):
2803 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002804 return None
andrewonlab7c211572014-10-15 16:45:20 -04002805 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002806 main.log.error( self.name + ": EOF exception found" )
2807 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002808 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002809 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002810 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002811 main.cleanAndExit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002812
kelvin-onlabd3b64892015-01-20 13:26:24 -08002813 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002814 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002815 Return the first device from the devices api whose 'id' contains 'dpid'
2816 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002817 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002818 try:
kelvin8ec71442015-01-15 16:57:00 -08002819 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002820 return None
2821 else:
kelvin8ec71442015-01-15 16:57:00 -08002822 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002823 rawDevices = self.devices()
2824 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002825 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002826 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002827 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2828 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002829 return device
2830 return None
Jon Hallc6793552016-01-19 14:18:37 -08002831 except ( TypeError, ValueError ):
2832 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002833 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002834 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002835 main.log.error( self.name + ": EOF exception found" )
2836 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002837 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002838 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002839 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002840 main.cleanAndExit()
Jon Halla91c4dc2014-10-22 12:57:04 -04002841
You Wang24139872016-05-03 11:48:47 -07002842 def getTopology( self, topologyOutput ):
2843 """
2844 Definition:
2845 Loads a json topology output
2846 Return:
2847 topology = current ONOS topology
2848 """
2849 import json
2850 try:
2851 # either onos:topology or 'topology' will work in CLI
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002852 topology = json.loads( topologyOutput )
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002853 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002854 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002855 except ( TypeError, ValueError ):
2856 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2857 return None
You Wang24139872016-05-03 11:48:47 -07002858 except pexpect.EOF:
2859 main.log.error( self.name + ": EOF exception found" )
2860 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002861 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07002862 except Exception:
2863 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002864 main.cleanAndExit()
You Wang24139872016-05-03 11:48:47 -07002865
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07002866 def checkStatus( self, numoswitch, numolink, numoctrl=-1, logLevel="info" ):
kelvin8ec71442015-01-15 16:57:00 -08002867 """
Jon Hallefbd9792015-03-05 16:11:36 -08002868 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002869 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002870 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002871
Flavio Castro82ee2f62016-06-07 15:04:12 -07002872 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002873 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002874 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002875 logLevel = level to log to.
2876 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002877
Jon Hallefbd9792015-03-05 16:11:36 -08002878 Returns: main.TRUE if the number of switches and links are correct,
2879 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002880 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002881 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07002882 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04002883 try:
You Wang13310252016-07-31 10:56:14 -07002884 summary = self.summary()
2885 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07002886 except ( TypeError, ValueError ):
2887 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
2888 return main.ERROR
2889 try:
2890 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07002891 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04002892 return main.ERROR
2893 output = ""
kelvin8ec71442015-01-15 16:57:00 -08002894 # Is the number of switches is what we expected
2895 devices = topology.get( 'devices', False )
2896 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002897 nodes = summary.get( 'nodes', False )
2898 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04002899 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08002900 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08002901 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08002902 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07002903 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
2904 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08002905 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07002906 output = output + "The number of links and switches match "\
2907 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002908 result = main.TRUE
2909 else:
You Wang24139872016-05-03 11:48:47 -07002910 output = output + \
2911 "The number of links and switches does not match " + \
2912 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04002913 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07002914 output = output + "\n ONOS sees %i devices" % int( devices )
2915 output = output + " (%i expected) " % int( numoswitch )
2916 output = output + "and %i links " % int( links )
2917 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07002918 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07002919 output = output + "and %i controllers " % int( nodes )
2920 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002921 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08002922 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002923 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08002924 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04002925 else:
You Wang24139872016-05-03 11:48:47 -07002926 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08002927 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04002928 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002929 main.log.error( self.name + ": EOF exception found" )
2930 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002931 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002932 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002933 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002934 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002935
kelvin-onlabd3b64892015-01-20 13:26:24 -08002936 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08002937 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002938 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08002939 deviceId must be the id of a device as seen in the onos devices command
2940 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04002941 role must be either master, standby, or none
2942
Jon Halle3f39ff2015-01-13 11:50:53 -08002943 Returns:
2944 main.TRUE or main.FALSE based on argument verification and
2945 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08002946 """
Jon Hall1c9e8732014-10-27 19:29:27 -04002947 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08002948 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04002949 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08002950 cmdStr = "device-role " +\
2951 str( deviceId ) + " " +\
2952 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08002953 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002954 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002955 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002956 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08002957 if re.search( "Error", handle ):
2958 # end color output to escape any colours
2959 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08002960 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08002961 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08002962 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08002963 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04002964 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08002965 main.log.error( "Invalid 'role' given to device_role(). " +
2966 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04002967 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002968 except AssertionError:
2969 main.log.exception( "" )
2970 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002971 except TypeError:
2972 main.log.exception( self.name + ": Object not as expected" )
2973 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04002974 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002975 main.log.error( self.name + ": EOF exception found" )
2976 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07002977 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002978 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002979 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07002980 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04002981
kelvin-onlabd3b64892015-01-20 13:26:24 -08002982 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002983 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002984 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08002985 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002986 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08002987 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08002988 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002989 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002990 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002991 cmdStr += " -j"
2992 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002993 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002994 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002995 return handle
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 Hall73cf9cc2014-11-20 22:28:38 -08003002 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 Hall73cf9cc2014-11-20 22:28:38 -08003009
kelvin-onlabd3b64892015-01-20 13:26:24 -08003010 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003011 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003012 CLI command to get the current leader for the Election test application
3013 NOTE: Requires installation of the onos-app-election feature
3014 Returns: Node IP of the leader if one exists
3015 None if none exists
3016 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003017 """
Jon Hall94fd0472014-12-08 11:52:42 -08003018 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003019 cmdStr = "election-test-leader"
3020 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003021 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003022 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003023 # Leader
3024 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003025 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003026 nodeSearch = re.search( leaderPattern, response )
3027 if nodeSearch:
3028 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003029 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003030 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003031 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003032 # no leader
3033 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003034 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003035 nullSearch = re.search( nullPattern, response )
3036 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003037 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003038 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003039 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003040 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003041 main.log.error( "Error in electionTestLeader on " + self.name +
3042 ": " + "unexpected response" )
3043 main.log.error( repr( response ) )
3044 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003045 except AssertionError:
3046 main.log.exception( "" )
3047 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003048 except TypeError:
3049 main.log.exception( self.name + ": Object not as expected" )
3050 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003051 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003052 main.log.error( self.name + ": EOF exception found" )
3053 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003054 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003055 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003056 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003057 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003058
kelvin-onlabd3b64892015-01-20 13:26:24 -08003059 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003060 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003061 CLI command to run for leadership of the Election test application.
3062 NOTE: Requires installation of the onos-app-election feature
3063 Returns: Main.TRUE on success
3064 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003065 """
Jon Hall94fd0472014-12-08 11:52:42 -08003066 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003067 cmdStr = "election-test-run"
3068 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003069 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003070 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003071 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003072 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003073 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003074 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003075 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003076 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003077 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003078 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003079 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003080 main.log.error( "Error in electionTestRun on " + self.name +
3081 ": " + "unexpected response" )
3082 main.log.error( repr( response ) )
3083 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003084 except AssertionError:
3085 main.log.exception( "" )
3086 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003087 except TypeError:
3088 main.log.exception( self.name + ": Object not as expected" )
3089 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003090 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003091 main.log.error( self.name + ": EOF exception found" )
3092 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003093 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003094 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003095 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003096 main.cleanAndExit()
Jon Hall94fd0472014-12-08 11:52:42 -08003097
kelvin-onlabd3b64892015-01-20 13:26:24 -08003098 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003099 """
Jon Hall94fd0472014-12-08 11:52:42 -08003100 * CLI command to withdraw the local node from leadership election for
3101 * the Election test application.
3102 #NOTE: Requires installation of the onos-app-election feature
3103 Returns: Main.TRUE on success
3104 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003105 """
Jon Hall94fd0472014-12-08 11:52:42 -08003106 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003107 cmdStr = "election-test-withdraw"
3108 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003109 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003110 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003111 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003112 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003113 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003114 if re.search( successPattern, response ):
3115 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003116 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003117 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003118 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003119 main.log.error( "Error in electionTestWithdraw on " +
3120 self.name + ": " + "unexpected response" )
3121 main.log.error( repr( response ) )
3122 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003123 except AssertionError:
3124 main.log.exception( "" )
3125 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003126 except TypeError:
3127 main.log.exception( self.name + ": Object not as expected" )
3128 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003129 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003130 main.log.error( self.name + ": EOF exception found" )
3131 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003132 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003133 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003134 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003135 main.cleanAndExit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003136
kelvin8ec71442015-01-15 16:57:00 -08003137 def getDevicePortsEnabledCount( self, dpid ):
3138 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003139 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003140 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003141 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003142 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003143 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3144 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003145 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003146 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003147 if re.search( "No such device", output ):
3148 main.log.error( "Error in getting ports" )
3149 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003150 return output
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 ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -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()
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003164
kelvin8ec71442015-01-15 16:57:00 -08003165 def getDeviceLinksActiveCount( 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:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003170 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003171 cmdStr = "onos:links " + dpid + " | grep ACTIVE | 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 ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003176 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 getAllIntentIds( self ):
3194 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003195 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003196 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003197 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003198 cmdStr = "onos:intents | grep id="
3199 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003200 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003201 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003202 if re.search( "Error", output ):
3203 main.log.error( "Error in getting ports" )
3204 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003205 return output
Jon Hallc6793552016-01-19 14:18:37 -08003206 except AssertionError:
3207 main.log.exception( "" )
3208 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003209 except TypeError:
3210 main.log.exception( self.name + ": Object not as expected" )
3211 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003212 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003213 main.log.error( self.name + ": EOF exception found" )
3214 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003215 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003216 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003217 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003218 main.cleanAndExit()
Jon Halld4d4b372015-01-28 16:02:41 -08003219
Jon Hall73509952015-02-24 16:42:56 -08003220 def intentSummary( self ):
3221 """
Jon Hallefbd9792015-03-05 16:11:36 -08003222 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003223 """
3224 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003225 intents = self.intents()
Jon Hall08f61bc2015-04-13 16:00:30 -07003226 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003227 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003228 states.append( intent.get( 'state', None ) )
3229 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003230 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003231 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003232 except ( TypeError, ValueError ):
3233 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003234 return None
3235 except pexpect.EOF:
3236 main.log.error( self.name + ": EOF exception found" )
3237 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003238 main.cleanAndExit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003239 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003240 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003241 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003242
Jon Hall61282e32015-03-19 11:34:11 -07003243 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003244 """
3245 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003246 Optional argument:
3247 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003248 """
Jon Hall63604932015-02-26 17:09:50 -08003249 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003250 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003251 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003252 cmdStr += " -j"
3253 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003254 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003255 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003256 return output
Jon Hallc6793552016-01-19 14:18:37 -08003257 except AssertionError:
3258 main.log.exception( "" )
3259 return None
Jon Hall63604932015-02-26 17:09:50 -08003260 except TypeError:
3261 main.log.exception( self.name + ": Object not as expected" )
3262 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003263 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 Hall77ba41c2015-04-06 10:25:40 -07003267 except Exception:
Jon Hall63604932015-02-26 17:09:50 -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
acsmarsa4a4d1e2015-07-10 16:01:24 -07003271 def leaderCandidates( self, jsonFormat=True ):
3272 """
3273 Returns the output of the leaders -c command.
3274 Optional argument:
3275 * jsonFormat - boolean indicating if you want output in json
3276 """
3277 try:
3278 cmdStr = "onos:leaders -c"
3279 if jsonFormat:
3280 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
acsmarsa4a4d1e2015-07-10 16:01:24 -07003284 return output
Jon Hallc6793552016-01-19 14:18:37 -08003285 except AssertionError:
3286 main.log.exception( "" )
3287 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003288 except TypeError:
3289 main.log.exception( self.name + ": Object not as expected" )
3290 return None
3291 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()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003295 except Exception:
3296 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003297 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003298
Jon Hallc6793552016-01-19 14:18:37 -08003299 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003300 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003301 Returns a list in format [ leader,candidate1,candidate2,... ] for a given
acsmarsa4a4d1e2015-07-10 16:01:24 -07003302 topic parameter and an empty list if the topic doesn't exist
3303 If no leader is elected leader in the returned list will be "none"
3304 Returns None if there is a type error processing the json object
3305 """
3306 try:
Jon Hall6e709752016-02-01 13:38:46 -08003307 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003308 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003309 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003310 assert "Command not found:" not in rawOutput, rawOutput
3311 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003312 results = []
3313 for dict in output:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003314 if dict[ "topic" ] == topic:
3315 leader = dict[ "leader" ]
3316 candidates = re.split( ", ", dict[ "candidates" ][ 1:-1 ] )
Jon Hallc6793552016-01-19 14:18:37 -08003317 results.append( leader )
3318 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003319 return results
Jon Hallc6793552016-01-19 14:18:37 -08003320 except AssertionError:
3321 main.log.exception( "" )
3322 return None
3323 except ( TypeError, ValueError ):
3324 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003325 return None
3326 except pexpect.EOF:
3327 main.log.error( self.name + ": EOF exception found" )
3328 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003329 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003330 except Exception:
3331 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003332 main.cleanAndExit()
acsmarsa4a4d1e2015-07-10 16:01:24 -07003333
Jon Hall61282e32015-03-19 11:34:11 -07003334 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003335 """
3336 Returns the output of the intent Pending map.
3337 """
Jon Hall63604932015-02-26 17:09:50 -08003338 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003339 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003340 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003341 cmdStr += " -j"
3342 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003343 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003344 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003345 return output
Jon Hallc6793552016-01-19 14:18:37 -08003346 except AssertionError:
3347 main.log.exception( "" )
3348 return None
Jon Hall63604932015-02-26 17:09:50 -08003349 except TypeError:
3350 main.log.exception( self.name + ": Object not as expected" )
3351 return None
3352 except pexpect.EOF:
3353 main.log.error( self.name + ": EOF exception found" )
3354 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003355 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003356 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003357 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003358 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003359
Jon Hall2c8959e2016-12-16 12:17:34 -08003360 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003361 """
3362 Returns the output of the raft partitions command for ONOS.
3363 """
Jon Hall61282e32015-03-19 11:34:11 -07003364 # Sample JSON
3365 # {
3366 # "leader": "tcp://10.128.30.11:7238",
3367 # "members": [
3368 # "tcp://10.128.30.11:7238",
3369 # "tcp://10.128.30.17:7238",
3370 # "tcp://10.128.30.13:7238",
3371 # ],
3372 # "name": "p1",
3373 # "term": 3
3374 # },
Jon Hall63604932015-02-26 17:09:50 -08003375 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003376 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003377 if candidates:
3378 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003379 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003380 cmdStr += " -j"
3381 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003382 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003383 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003384 return output
Jon Hallc6793552016-01-19 14:18:37 -08003385 except AssertionError:
3386 main.log.exception( "" )
3387 return None
Jon Hall63604932015-02-26 17:09:50 -08003388 except TypeError:
3389 main.log.exception( self.name + ": Object not as expected" )
3390 return None
3391 except pexpect.EOF:
3392 main.log.error( self.name + ": EOF exception found" )
3393 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003394 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003395 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003396 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003397 main.cleanAndExit()
Jon Hall63604932015-02-26 17:09:50 -08003398
Jon Halle9f909e2016-09-23 10:43:12 -07003399 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003400 """
3401 Returns the output of the apps command for ONOS. This command lists
3402 information about installed ONOS applications
3403 """
3404 # Sample JSON object
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003405 # [ { "name":"org.onosproject.openflow","id":0,"version":"1.2.0",
Jon Hallbe379602015-03-24 13:39:32 -07003406 # "description":"ONOS OpenFlow protocol southbound providers",
3407 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003408 # "features":"[onos-openflow]","state":"ACTIVE" } ]
Jon Hallbe379602015-03-24 13:39:32 -07003409 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003410 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003411 if summary:
3412 cmdStr += " -s"
3413 if active:
3414 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003415 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003416 cmdStr += " -j"
3417 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003418 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003419 assert "Command not found:" not in output, output
3420 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003421 return output
Jon Hallbe379602015-03-24 13:39:32 -07003422 # FIXME: look at specific exceptions/Errors
3423 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003424 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003425 return None
3426 except TypeError:
3427 main.log.exception( self.name + ": Object not as expected" )
3428 return None
3429 except pexpect.EOF:
3430 main.log.error( self.name + ": EOF exception found" )
3431 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003432 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003433 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003434 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003435 main.cleanAndExit()
Jon Hallbe379602015-03-24 13:39:32 -07003436
Jon Hall146f1522015-03-24 15:33:24 -07003437 def appStatus( self, appName ):
3438 """
3439 Uses the onos:apps cli command to return the status of an application.
3440 Returns:
3441 "ACTIVE" - If app is installed and activated
3442 "INSTALLED" - If app is installed and deactivated
3443 "UNINSTALLED" - If app is not installed
3444 None - on error
3445 """
Jon Hall146f1522015-03-24 15:33:24 -07003446 try:
3447 if not isinstance( appName, types.StringType ):
3448 main.log.error( self.name + ".appStatus(): appName must be" +
3449 " a string" )
3450 return None
3451 output = self.apps( jsonFormat=True )
3452 appsJson = json.loads( output )
3453 state = None
3454 for app in appsJson:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003455 if appName == app.get( 'name' ):
3456 state = app.get( 'state' )
Jon Hall146f1522015-03-24 15:33:24 -07003457 break
3458 if state == "ACTIVE" or state == "INSTALLED":
3459 return state
3460 elif state is None:
Jon Hall8bafdc02017-09-05 11:36:26 -07003461 main.log.warn( "{} app not found", appName )
Jon Hall146f1522015-03-24 15:33:24 -07003462 return "UNINSTALLED"
3463 elif state:
3464 main.log.error( "Unexpected state from 'onos:apps': " +
3465 str( state ) )
3466 return state
Jon Hallc6793552016-01-19 14:18:37 -08003467 except ( TypeError, ValueError ):
3468 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003469 return None
3470 except pexpect.EOF:
3471 main.log.error( self.name + ": EOF exception found" )
3472 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003473 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003474 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003475 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003476 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003477
Jon Hallbe379602015-03-24 13:39:32 -07003478 def app( self, appName, option ):
3479 """
3480 Interacts with the app command for ONOS. This command manages
3481 application inventory.
3482 """
Jon Hallbe379602015-03-24 13:39:32 -07003483 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003484 # Validate argument types
3485 valid = True
3486 if not isinstance( appName, types.StringType ):
3487 main.log.error( self.name + ".app(): appName must be a " +
3488 "string" )
3489 valid = False
3490 if not isinstance( option, types.StringType ):
3491 main.log.error( self.name + ".app(): option must be a string" )
3492 valid = False
3493 if not valid:
3494 return main.FALSE
3495 # Validate Option
3496 option = option.lower()
3497 # NOTE: Install may become a valid option
3498 if option == "activate":
3499 pass
3500 elif option == "deactivate":
3501 pass
3502 elif option == "uninstall":
3503 pass
3504 else:
3505 # Invalid option
3506 main.log.error( "The ONOS app command argument only takes " +
3507 "the values: (activate|deactivate|uninstall)" +
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003508 "; was given '" + option + "'" )
Jon Hallbd16b922015-03-26 17:53:15 -07003509 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003510 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003511 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003512 assert output is not None, "Error in sendline"
3513 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003514 if "Error executing command" in output:
3515 main.log.error( "Error in processing onos:app command: " +
3516 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003517 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003518 elif "No such application" in output:
3519 main.log.error( "The application '" + appName +
3520 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003521 return main.FALSE
3522 elif "Command not found:" in output:
3523 main.log.error( "Error in processing onos:app command: " +
3524 str( output ) )
3525 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003526 elif "Unsupported command:" in output:
3527 main.log.error( "Incorrect command given to 'app': " +
3528 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003529 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003530 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003531 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003532 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003533 except AssertionError:
3534 main.log.exception( self.name + ": AssertionError exception found" )
3535 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003536 except TypeError:
3537 main.log.exception( self.name + ": Object not as expected" )
3538 return main.ERROR
3539 except pexpect.EOF:
3540 main.log.error( self.name + ": EOF exception found" )
3541 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003542 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003543 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003544 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003545 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003546
Jon Hallbd16b922015-03-26 17:53:15 -07003547 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003548 """
3549 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003550 appName is the hierarchical app name, not the feature name
3551 If check is True, method will check the status of the app after the
3552 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003553 Returns main.TRUE if the command was successfully sent
3554 main.FALSE if the cli responded with an error or given
3555 incorrect input
3556 """
3557 try:
3558 if not isinstance( appName, types.StringType ):
3559 main.log.error( self.name + ".activateApp(): appName must be" +
3560 " a string" )
3561 return main.FALSE
3562 status = self.appStatus( appName )
3563 if status == "INSTALLED":
3564 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003565 if check and response == main.TRUE:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003566 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003567 status = self.appStatus( appName )
3568 if status == "ACTIVE":
3569 return main.TRUE
3570 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003571 main.log.debug( "The state of application " +
3572 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003573 time.sleep( 1 )
3574 return main.FALSE
3575 else: # not 'check' or command didn't succeed
3576 return response
Jon Hall146f1522015-03-24 15:33:24 -07003577 elif status == "ACTIVE":
3578 return main.TRUE
3579 elif status == "UNINSTALLED":
3580 main.log.error( self.name + ": Tried to activate the " +
3581 "application '" + appName + "' which is not " +
3582 "installed." )
3583 else:
3584 main.log.error( "Unexpected return value from appStatus: " +
3585 str( status ) )
3586 return main.ERROR
3587 except TypeError:
3588 main.log.exception( self.name + ": Object not as expected" )
3589 return main.ERROR
3590 except pexpect.EOF:
3591 main.log.error( self.name + ": EOF exception found" )
3592 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003593 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003594 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003595 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003596 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003597
Jon Hallbd16b922015-03-26 17:53:15 -07003598 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003599 """
3600 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003601 appName is the hierarchical app name, not the feature name
3602 If check is True, method will check the status of the app after the
3603 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003604 Returns main.TRUE if the command was successfully sent
3605 main.FALSE if the cli responded with an error or given
3606 incorrect input
3607 """
3608 try:
3609 if not isinstance( appName, types.StringType ):
3610 main.log.error( self.name + ".deactivateApp(): appName must " +
3611 "be a string" )
3612 return main.FALSE
3613 status = self.appStatus( appName )
3614 if status == "INSTALLED":
3615 return main.TRUE
3616 elif status == "ACTIVE":
3617 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003618 if check and response == main.TRUE:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003619 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003620 status = self.appStatus( appName )
3621 if status == "INSTALLED":
3622 return main.TRUE
3623 else:
3624 time.sleep( 1 )
3625 return main.FALSE
3626 else: # not check or command didn't succeed
3627 return response
Jon Hall146f1522015-03-24 15:33:24 -07003628 elif status == "UNINSTALLED":
3629 main.log.warn( self.name + ": Tried to deactivate the " +
3630 "application '" + appName + "' which is not " +
3631 "installed." )
3632 return main.TRUE
3633 else:
3634 main.log.error( "Unexpected return value from appStatus: " +
3635 str( status ) )
3636 return main.ERROR
3637 except TypeError:
3638 main.log.exception( self.name + ": Object not as expected" )
3639 return main.ERROR
3640 except pexpect.EOF:
3641 main.log.error( self.name + ": EOF exception found" )
3642 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003643 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003644 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003645 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003646 main.cleanAndExit()
Jon Hall146f1522015-03-24 15:33:24 -07003647
Jon Hallbd16b922015-03-26 17:53:15 -07003648 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003649 """
3650 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003651 appName is the hierarchical app name, not the feature name
3652 If check is True, method will check the status of the app after the
3653 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003654 Returns main.TRUE if the command was successfully sent
3655 main.FALSE if the cli responded with an error or given
3656 incorrect input
3657 """
3658 # TODO: check with Thomas about the state machine for apps
3659 try:
3660 if not isinstance( appName, types.StringType ):
3661 main.log.error( self.name + ".uninstallApp(): appName must " +
3662 "be a string" )
3663 return main.FALSE
3664 status = self.appStatus( appName )
3665 if status == "INSTALLED":
3666 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003667 if check and response == main.TRUE:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003668 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003669 status = self.appStatus( appName )
3670 if status == "UNINSTALLED":
3671 return main.TRUE
3672 else:
3673 time.sleep( 1 )
3674 return main.FALSE
3675 else: # not check or command didn't succeed
3676 return response
Jon Hall146f1522015-03-24 15:33:24 -07003677 elif status == "ACTIVE":
3678 main.log.warn( self.name + ": Tried to uninstall the " +
3679 "application '" + appName + "' which is " +
3680 "currently active." )
3681 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003682 if check and response == main.TRUE:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003683 for i in range( 10 ): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003684 status = self.appStatus( appName )
3685 if status == "UNINSTALLED":
3686 return main.TRUE
3687 else:
3688 time.sleep( 1 )
3689 return main.FALSE
3690 else: # not check or command didn't succeed
3691 return response
Jon Hall146f1522015-03-24 15:33:24 -07003692 elif status == "UNINSTALLED":
3693 return main.TRUE
3694 else:
3695 main.log.error( "Unexpected return value from appStatus: " +
3696 str( status ) )
3697 return main.ERROR
3698 except TypeError:
3699 main.log.exception( self.name + ": Object not as expected" )
3700 return main.ERROR
3701 except pexpect.EOF:
3702 main.log.error( self.name + ": EOF exception found" )
3703 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003704 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003705 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003706 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003707 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003708
3709 def appIDs( self, jsonFormat=True ):
3710 """
3711 Show the mappings between app id and app names given by the 'app-ids'
3712 cli command
3713 """
3714 try:
3715 cmdStr = "app-ids"
3716 if jsonFormat:
3717 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003718 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003719 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003720 assert "Command not found:" not in output, output
3721 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003722 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003723 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003724 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003725 return None
3726 except TypeError:
3727 main.log.exception( self.name + ": Object not as expected" )
3728 return None
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 Hallbd16b922015-03-26 17:53:15 -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 appToIDCheck( self ):
3738 """
3739 This method will check that each application's ID listed in 'apps' is
3740 the same as the ID listed in 'app-ids'. The check will also check that
3741 there are no duplicate IDs issued. Note that an app ID should be
3742 a globaly unique numerical identifier for app/app-like features. Once
3743 an ID is registered, the ID is never freed up so that if an app is
3744 reinstalled it will have the same ID.
3745
3746 Returns: main.TRUE if the check passes and
3747 main.FALSE if the check fails or
3748 main.ERROR if there is some error in processing the test
3749 """
3750 try:
Jon Hall390696c2015-05-05 17:13:41 -07003751 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003752 rawJson = self.appIDs( jsonFormat=True )
3753 if rawJson:
3754 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003755 else:
Jon Hallc6793552016-01-19 14:18:37 -08003756 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003757 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003758 rawJson = self.apps( jsonFormat=True )
3759 if rawJson:
3760 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003761 else:
Jon Hallc6793552016-01-19 14:18:37 -08003762 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003763 bail = True
3764 if bail:
3765 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003766 result = main.TRUE
3767 for app in apps:
3768 appID = app.get( 'id' )
3769 if appID is None:
3770 main.log.error( "Error parsing app: " + str( app ) )
3771 result = main.FALSE
3772 appName = app.get( 'name' )
3773 if appName is None:
3774 main.log.error( "Error parsing app: " + str( app ) )
3775 result = main.FALSE
3776 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003777 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003778 # main.log.debug( "Comparing " + str( app ) + " to " +
3779 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003780 if not current: # if ids doesn't have this id
3781 result = main.FALSE
3782 main.log.error( "'app-ids' does not have the ID for " +
3783 str( appName ) + " that apps does." )
3784 elif len( current ) > 1:
3785 # there is more than one app with this ID
3786 result = main.FALSE
3787 # We will log this later in the method
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003788 elif not current[ 0 ][ 'name' ] == appName:
3789 currentName = current[ 0 ][ 'name' ]
Jon Hallbd16b922015-03-26 17:53:15 -07003790 result = main.FALSE
3791 main.log.error( "'app-ids' has " + str( currentName ) +
3792 " registered under id:" + str( appID ) +
3793 " but 'apps' has " + str( appName ) )
3794 else:
3795 pass # id and name match!
3796 # now make sure that app-ids has no duplicates
3797 idsList = []
3798 namesList = []
3799 for item in ids:
3800 idsList.append( item[ 'id' ] )
3801 namesList.append( item[ 'name' ] )
3802 if len( idsList ) != len( set( idsList ) ) or\
3803 len( namesList ) != len( set( namesList ) ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003804 main.log.error( "'app-ids' has some duplicate entries: \n"
3805 + json.dumps( ids,
3806 sort_keys=True,
3807 indent=4,
3808 separators=( ',', ': ' ) ) )
3809 result = main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003810 return result
Jon Hallc6793552016-01-19 14:18:37 -08003811 except ( TypeError, ValueError ):
3812 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003813 return main.ERROR
3814 except pexpect.EOF:
3815 main.log.error( self.name + ": EOF exception found" )
3816 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003817 main.cleanAndExit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003818 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003819 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003820 main.cleanAndExit()
Jon Hallbd16b922015-03-26 17:53:15 -07003821
Jon Hallfb760a02015-04-13 15:35:03 -07003822 def getCfg( self, component=None, propName=None, short=False,
3823 jsonFormat=True ):
3824 """
3825 Get configuration settings from onos cli
3826 Optional arguments:
3827 component - Optionally only list configurations for a specific
3828 component. If None, all components with configurations
3829 are displayed. Case Sensitive string.
3830 propName - If component is specified, propName option will show
3831 only this specific configuration from that component.
3832 Case Sensitive string.
3833 jsonFormat - Returns output as json. Note that this will override
3834 the short option
3835 short - Short, less verbose, version of configurations.
3836 This is overridden by the json option
3837 returns:
3838 Output from cli as a string or None on error
3839 """
3840 try:
3841 baseStr = "cfg"
3842 cmdStr = " get"
3843 componentStr = ""
3844 if component:
3845 componentStr += " " + component
3846 if propName:
3847 componentStr += " " + propName
3848 if jsonFormat:
3849 baseStr += " -j"
3850 elif short:
3851 baseStr += " -s"
3852 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07003853 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003854 assert "Command not found:" not in output, output
3855 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003856 return output
3857 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003858 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003859 return None
3860 except TypeError:
3861 main.log.exception( self.name + ": Object not as expected" )
3862 return None
3863 except pexpect.EOF:
3864 main.log.error( self.name + ": EOF exception found" )
3865 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003866 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003867 except Exception:
3868 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003869 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003870
3871 def setCfg( self, component, propName, value=None, check=True ):
3872 """
3873 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07003874 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003875 component - The case sensitive name of the component whose
3876 property is to be set
3877 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07003878 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07003879 value - The value to set the property to. If None, will unset the
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003880 property and revert it to it's default value( if applicable )
Jon Hallfb760a02015-04-13 15:35:03 -07003881 check - Boolean, Check whether the option was successfully set this
3882 only applies when a value is given.
3883 returns:
3884 main.TRUE on success or main.FALSE on failure. If check is False,
3885 will return main.TRUE unless there is an error
3886 """
3887 try:
3888 baseStr = "cfg"
3889 cmdStr = " set " + str( component ) + " " + str( propName )
3890 if value is not None:
3891 cmdStr += " " + str( value )
3892 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003893 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003894 assert "Command not found:" not in output, output
3895 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07003896 if value and check:
3897 results = self.getCfg( component=str( component ),
3898 propName=str( propName ),
3899 jsonFormat=True )
3900 # Check if current value is what we just set
3901 try:
3902 jsonOutput = json.loads( results )
3903 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08003904 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07003905 main.log.exception( "Error parsing cfg output" )
3906 main.log.error( "output:" + repr( results ) )
3907 return main.FALSE
3908 if current == str( value ):
3909 return main.TRUE
3910 return main.FALSE
3911 return main.TRUE
3912 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003913 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07003914 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003915 except ( TypeError, ValueError ):
3916 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07003917 return main.FALSE
3918 except pexpect.EOF:
3919 main.log.error( self.name + ": EOF exception found" )
3920 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003921 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003922 except Exception:
3923 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003924 main.cleanAndExit()
Jon Hallfb760a02015-04-13 15:35:03 -07003925
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003926 def distPrimitivesSend( self, cmd ):
3927 """
3928 Function to handle sending cli commands for the distributed primitives test app
3929
3930 This command will catch some exceptions and retry the command on some
3931 specific store exceptions.
3932
3933 Required arguments:
3934 cmd - The command to send to the cli
3935 returns:
3936 string containing the cli output
3937 None on Error
3938 """
3939 try:
3940 output = self.sendline( cmd )
3941 try:
3942 assert output is not None, "Error in sendline"
3943 # TODO: Maybe make this less hardcoded
3944 # ConsistentMap Exceptions
3945 assert "org.onosproject.store.service" not in output
3946 # Node not leader
3947 assert "java.lang.IllegalStateException" not in output
3948 except AssertionError:
3949 main.log.error( "Error in processing '" + cmd + "' " +
3950 "command: " + str( output ) )
3951 retryTime = 30 # Conservative time, given by Madan
3952 main.log.info( "Waiting " + str( retryTime ) +
3953 "seconds before retrying." )
3954 time.sleep( retryTime ) # Due to change in mastership
3955 output = self.sendline( cmd )
3956 assert output is not None, "Error in sendline"
3957 assert "Command not found:" not in output, output
3958 assert "Error executing command" not in output, output
3959 main.log.info( self.name + ": " + output )
3960 return output
3961 except AssertionError:
3962 main.log.exception( "Error in processing '" + cmd + "' command." )
3963 return None
3964 except TypeError:
3965 main.log.exception( self.name + ": Object not as expected" )
3966 return None
3967 except pexpect.EOF:
3968 main.log.error( self.name + ": EOF exception found" )
3969 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07003970 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003971 except Exception:
3972 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07003973 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003974
Jon Hall390696c2015-05-05 17:13:41 -07003975 def setTestAdd( self, setName, values ):
3976 """
3977 CLI command to add elements to a distributed set.
3978 Arguments:
3979 setName - The name of the set to add to.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003980 values - The value( s ) to add to the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07003981 Example usages:
3982 setTestAdd( "set1", "a b c" )
3983 setTestAdd( "set2", "1" )
3984 returns:
3985 main.TRUE on success OR
3986 main.FALSE if elements were already in the set OR
3987 main.ERROR on error
3988 """
3989 try:
3990 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07003991 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07003992 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
3993 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003994 if re.search( positiveMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07003995 return main.TRUE
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07003996 elif re.search( negativeMatch, output ):
Jon Hall390696c2015-05-05 17:13:41 -07003997 return main.FALSE
3998 else:
3999 main.log.error( self.name + ": setTestAdd did not" +
4000 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004001 main.log.debug( self.name + " actual: " + repr( output ) )
4002 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004003 except TypeError:
4004 main.log.exception( self.name + ": Object not as expected" )
4005 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004006 except Exception:
4007 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004008 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004009
4010 def setTestRemove( self, setName, values, clear=False, retain=False ):
4011 """
4012 CLI command to remove elements from a distributed set.
4013 Required arguments:
4014 setName - The name of the set to remove from.
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004015 values - The value( s ) to remove from the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004016 Optional arguments:
4017 clear - Clear all elements from the set
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004018 retain - Retain only the given values. ( intersection of the
4019 original set and the given set )
Jon Hall390696c2015-05-05 17:13:41 -07004020 returns:
4021 main.TRUE on success OR
4022 main.FALSE if the set was not changed OR
4023 main.ERROR on error
4024 """
4025 try:
4026 cmdStr = "set-test-remove "
4027 if clear:
4028 cmdStr += "-c " + str( setName )
4029 elif retain:
4030 cmdStr += "-r " + str( setName ) + " " + str( values )
4031 else:
4032 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004033 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004034 if clear:
4035 pattern = "Set " + str( setName ) + " cleared"
4036 if re.search( pattern, output ):
4037 return main.TRUE
4038 elif retain:
4039 positivePattern = str( setName ) + " was pruned to contain " +\
4040 "only elements of set \[(.*)\]"
4041 negativePattern = str( setName ) + " was not changed by " +\
4042 "retaining only elements of the set " +\
4043 "\[(.*)\]"
4044 if re.search( positivePattern, output ):
4045 return main.TRUE
4046 elif re.search( negativePattern, output ):
4047 return main.FALSE
4048 else:
4049 positivePattern = "\[(.*)\] was removed from the set " +\
4050 str( setName )
4051 if ( len( values.split() ) == 1 ):
4052 negativePattern = "\[(.*)\] was not in set " +\
4053 str( setName )
4054 else:
4055 negativePattern = "No element of \[(.*)\] was in set " +\
4056 str( setName )
4057 if re.search( positivePattern, output ):
4058 return main.TRUE
4059 elif re.search( negativePattern, output ):
4060 return main.FALSE
4061 main.log.error( self.name + ": setTestRemove did not" +
4062 " match expected output" )
4063 main.log.debug( self.name + " expected: " + pattern )
4064 main.log.debug( self.name + " actual: " + repr( output ) )
4065 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004066 except TypeError:
4067 main.log.exception( self.name + ": Object not as expected" )
4068 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004069 except Exception:
4070 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004071 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004072
4073 def setTestGet( self, setName, values="" ):
4074 """
4075 CLI command to get the elements in a distributed set.
4076 Required arguments:
4077 setName - The name of the set to remove from.
4078 Optional arguments:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004079 values - The value( s ) to check if in the set, space seperated.
Jon Hall390696c2015-05-05 17:13:41 -07004080 returns:
4081 main.ERROR on error OR
4082 A list of elements in the set if no optional arguments are
4083 supplied OR
4084 A tuple containing the list then:
4085 main.FALSE if the given values are not in the set OR
4086 main.TRUE if the given values are in the set OR
4087 """
4088 try:
4089 values = str( values ).strip()
4090 setName = str( setName ).strip()
4091 length = len( values.split() )
4092 containsCheck = None
4093 # Patterns to match
4094 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004095 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004096 containsTrue = "Set " + setName + " contains the value " + values
4097 containsFalse = "Set " + setName + " did not contain the value " +\
4098 values
4099 containsAllTrue = "Set " + setName + " contains the the subset " +\
4100 setPattern
4101 containsAllFalse = "Set " + setName + " did not contain the the" +\
4102 " subset " + setPattern
4103
4104 cmdStr = "set-test-get "
4105 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004106 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004107 if length == 0:
4108 match = re.search( pattern, output )
4109 else: # if given values
4110 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004111 patternTrue = pattern + "\r\n" + containsTrue
4112 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004113 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004114 patternTrue = pattern + "\r\n" + containsAllTrue
4115 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004116 matchTrue = re.search( patternTrue, output )
4117 matchFalse = re.search( patternFalse, output )
4118 if matchTrue:
4119 containsCheck = main.TRUE
4120 match = matchTrue
4121 elif matchFalse:
4122 containsCheck = main.FALSE
4123 match = matchFalse
4124 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004125 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004126 "expected output" )
4127 main.log.debug( self.name + " expected: " + pattern )
4128 main.log.debug( self.name + " actual: " + repr( output ) )
4129 match = None
4130 if match:
4131 setMatch = match.group( 1 )
4132 if setMatch == '':
4133 setList = []
4134 else:
4135 setList = setMatch.split( ", " )
4136 if length > 0:
4137 return ( setList, containsCheck )
4138 else:
4139 return setList
4140 else: # no match
4141 main.log.error( self.name + ": setTestGet did not" +
4142 " match expected output" )
4143 main.log.debug( self.name + " expected: " + pattern )
4144 main.log.debug( self.name + " actual: " + repr( output ) )
4145 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004146 except TypeError:
4147 main.log.exception( self.name + ": Object not as expected" )
4148 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004149 except Exception:
4150 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004151 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004152
4153 def setTestSize( self, setName ):
4154 """
4155 CLI command to get the elements in a distributed set.
4156 Required arguments:
4157 setName - The name of the set to remove from.
4158 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004159 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004160 None on error
4161 """
4162 try:
4163 # TODO: Should this check against the number of elements returned
4164 # and then return true/false based on that?
4165 setName = str( setName ).strip()
4166 # Patterns to match
4167 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004168 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004169 setPattern
4170 cmdStr = "set-test-get -s "
4171 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004172 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004173 match = re.search( pattern, output )
4174 if match:
4175 setSize = int( match.group( 1 ) )
4176 setMatch = match.group( 2 )
4177 if len( setMatch.split() ) == setSize:
4178 main.log.info( "The size returned by " + self.name +
4179 " matches the number of elements in " +
4180 "the returned set" )
4181 else:
4182 main.log.error( "The size returned by " + self.name +
4183 " does not match the number of " +
4184 "elements in the returned set." )
4185 return setSize
4186 else: # no match
4187 main.log.error( self.name + ": setTestGet did not" +
4188 " match expected output" )
4189 main.log.debug( self.name + " expected: " + pattern )
4190 main.log.debug( self.name + " actual: " + repr( output ) )
4191 return None
Jon Hall390696c2015-05-05 17:13:41 -07004192 except TypeError:
4193 main.log.exception( self.name + ": Object not as expected" )
4194 return None
Jon Hall390696c2015-05-05 17:13:41 -07004195 except Exception:
4196 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004197 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004198
Jon Hall80daded2015-05-27 16:07:00 -07004199 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004200 """
4201 Command to list the various counters in the system.
4202 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004203 if jsonFormat, a string of the json object returned by the cli
4204 command
4205 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004206 None on error
4207 """
Jon Hall390696c2015-05-05 17:13:41 -07004208 try:
Jon Hall390696c2015-05-05 17:13:41 -07004209 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004210 if jsonFormat:
4211 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004212 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004213 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004214 assert "Command not found:" not in output, output
4215 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004216 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004217 return output
Jon Hall390696c2015-05-05 17:13:41 -07004218 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004219 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004220 return None
Jon Hall390696c2015-05-05 17:13:41 -07004221 except TypeError:
4222 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004223 return None
Jon Hall390696c2015-05-05 17:13:41 -07004224 except pexpect.EOF:
4225 main.log.error( self.name + ": EOF exception found" )
4226 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004227 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004228 except Exception:
4229 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004230 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004231
Jon Hall935db192016-04-19 00:22:04 -07004232 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004233 """
Jon Halle1a3b752015-07-22 13:02:46 -07004234 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004235 Required arguments:
4236 counter - The name of the counter to increment.
4237 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004238 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004239 returns:
4240 integer value of the counter or
4241 None on Error
4242 """
4243 try:
4244 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004245 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004246 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004247 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004248 if delta != 1:
4249 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004250 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004251 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004252 match = re.search( pattern, output )
4253 if match:
4254 return int( match.group( 1 ) )
4255 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004256 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004257 " match expected output." )
4258 main.log.debug( self.name + " expected: " + pattern )
4259 main.log.debug( self.name + " actual: " + repr( output ) )
4260 return None
Jon Hall390696c2015-05-05 17:13:41 -07004261 except TypeError:
4262 main.log.exception( self.name + ": Object not as expected" )
4263 return None
Jon Hall390696c2015-05-05 17:13:41 -07004264 except Exception:
4265 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004266 main.cleanAndExit()
Jon Hall390696c2015-05-05 17:13:41 -07004267
Jon Hall935db192016-04-19 00:22:04 -07004268 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004269 """
4270 CLI command to get a distributed counter then add a delta to it.
4271 Required arguments:
4272 counter - The name of the counter to increment.
4273 Optional arguments:
4274 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004275 returns:
4276 integer value of the counter or
4277 None on Error
4278 """
4279 try:
4280 counter = str( counter )
4281 delta = int( delta )
4282 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004283 cmdStr += counter
4284 if delta != 1:
4285 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004286 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004287 pattern = counter + " was updated to (-?\d+)"
4288 match = re.search( pattern, output )
4289 if match:
4290 return int( match.group( 1 ) )
4291 else:
4292 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4293 " match expected output." )
4294 main.log.debug( self.name + " expected: " + pattern )
4295 main.log.debug( self.name + " actual: " + repr( output ) )
4296 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004297 except TypeError:
4298 main.log.exception( self.name + ": Object not as expected" )
4299 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004300 except Exception:
4301 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004302 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004303
4304 def valueTestGet( self, valueName ):
4305 """
4306 CLI command to get the value of an atomic value.
4307 Required arguments:
4308 valueName - The name of the value to get.
4309 returns:
4310 string value of the value or
4311 None on Error
4312 """
4313 try:
4314 valueName = str( valueName )
4315 cmdStr = "value-test "
4316 operation = "get"
4317 cmdStr = "value-test {} {}".format( valueName,
4318 operation )
4319 output = self.distPrimitivesSend( cmdStr )
4320 pattern = "(\w+)"
4321 match = re.search( pattern, output )
4322 if match:
4323 return match.group( 1 )
4324 else:
4325 main.log.error( self.name + ": valueTestGet did not" +
4326 " match expected output." )
4327 main.log.debug( self.name + " expected: " + pattern )
4328 main.log.debug( self.name + " actual: " + repr( output ) )
4329 return None
4330 except TypeError:
4331 main.log.exception( self.name + ": Object not as expected" )
4332 return None
4333 except Exception:
4334 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004335 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004336
4337 def valueTestSet( self, valueName, newValue ):
4338 """
4339 CLI command to set the value of an atomic value.
4340 Required arguments:
4341 valueName - The name of the value to set.
4342 newValue - The value to assign to the given value.
4343 returns:
4344 main.TRUE on success or
4345 main.ERROR on Error
4346 """
4347 try:
4348 valueName = str( valueName )
4349 newValue = str( newValue )
4350 operation = "set"
4351 cmdStr = "value-test {} {} {}".format( valueName,
4352 operation,
4353 newValue )
4354 output = self.distPrimitivesSend( cmdStr )
4355 if output is not None:
4356 return main.TRUE
4357 else:
4358 return main.ERROR
4359 except TypeError:
4360 main.log.exception( self.name + ": Object not as expected" )
4361 return main.ERROR
4362 except Exception:
4363 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004364 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004365
4366 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4367 """
4368 CLI command to compareAndSet the value of an atomic value.
4369 Required arguments:
4370 valueName - The name of the value.
4371 oldValue - Compare the current value of the atomic value to this
4372 newValue - If the value equals oldValue, set the value to newValue
4373 returns:
4374 main.TRUE on success or
4375 main.FALSE on failure or
4376 main.ERROR on Error
4377 """
4378 try:
4379 valueName = str( valueName )
4380 oldValue = str( oldValue )
4381 newValue = str( newValue )
4382 operation = "compareAndSet"
4383 cmdStr = "value-test {} {} {} {}".format( valueName,
4384 operation,
4385 oldValue,
4386 newValue )
4387 output = self.distPrimitivesSend( cmdStr )
4388 pattern = "(\w+)"
4389 match = re.search( pattern, output )
4390 if match:
4391 result = match.group( 1 )
4392 if result == "true":
4393 return main.TRUE
4394 elif result == "false":
4395 return main.FALSE
4396 else:
4397 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4398 " match expected output." )
4399 main.log.debug( self.name + " expected: " + pattern )
4400 main.log.debug( self.name + " actual: " + repr( output ) )
4401 return main.ERROR
4402 except TypeError:
4403 main.log.exception( self.name + ": Object not as expected" )
4404 return main.ERROR
4405 except Exception:
4406 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004407 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004408
4409 def valueTestGetAndSet( self, valueName, newValue ):
4410 """
4411 CLI command to getAndSet the value of an atomic value.
4412 Required arguments:
4413 valueName - The name of the value to get.
4414 newValue - The value to assign to the given value
4415 returns:
4416 string value of the value or
4417 None on Error
4418 """
4419 try:
4420 valueName = str( valueName )
4421 cmdStr = "value-test "
4422 operation = "getAndSet"
4423 cmdStr += valueName + " " + operation
4424 cmdStr = "value-test {} {} {}".format( valueName,
4425 operation,
4426 newValue )
4427 output = self.distPrimitivesSend( cmdStr )
4428 pattern = "(\w+)"
4429 match = re.search( pattern, output )
4430 if match:
4431 return match.group( 1 )
4432 else:
4433 main.log.error( self.name + ": valueTestGetAndSet did not" +
4434 " match expected output." )
4435 main.log.debug( self.name + " expected: " + pattern )
4436 main.log.debug( self.name + " actual: " + repr( output ) )
4437 return None
4438 except TypeError:
4439 main.log.exception( self.name + ": Object not as expected" )
4440 return None
4441 except Exception:
4442 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004443 main.cleanAndExit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004444
4445 def valueTestDestroy( self, valueName ):
4446 """
4447 CLI command to destroy an atomic value.
4448 Required arguments:
4449 valueName - The name of the value to destroy.
4450 returns:
4451 main.TRUE on success or
4452 main.ERROR on Error
4453 """
4454 try:
4455 valueName = str( valueName )
4456 cmdStr = "value-test "
4457 operation = "destroy"
4458 cmdStr += valueName + " " + operation
4459 output = self.distPrimitivesSend( cmdStr )
4460 if output is not None:
4461 return main.TRUE
4462 else:
4463 return main.ERROR
4464 except TypeError:
4465 main.log.exception( self.name + ": Object not as expected" )
4466 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004467 except Exception:
4468 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004469 main.cleanAndExit()
Jon Halle1a3b752015-07-22 13:02:46 -07004470
YPZhangfebf7302016-05-24 16:45:56 -07004471 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004472 """
4473 Description: Execute summary command in onos
4474 Returns: json object ( summary -j ), returns main.FALSE if there is
4475 no output
4476
4477 """
4478 try:
4479 cmdStr = "summary"
4480 if jsonFormat:
4481 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004482 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004483 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004484 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004485 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004486 if not handle:
4487 main.log.error( self.name + ": There is no output in " +
4488 "summary command" )
4489 return main.FALSE
4490 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004491 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004492 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004493 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004494 except TypeError:
4495 main.log.exception( self.name + ": Object not as expected" )
4496 return None
4497 except pexpect.EOF:
4498 main.log.error( self.name + ": EOF exception found" )
4499 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004500 main.cleanAndExit()
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004501 except Exception:
4502 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004503 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004504
Jon Hall935db192016-04-19 00:22:04 -07004505 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004506 """
4507 CLI command to get the value of a key in a consistent map using
4508 transactions. This a test function and can only get keys from the
4509 test map hard coded into the cli command
4510 Required arguments:
4511 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004512 returns:
4513 The string value of the key or
4514 None on Error
4515 """
4516 try:
4517 keyName = str( keyName )
4518 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004519 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004520 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004521 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4522 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004523 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004524 return None
4525 else:
4526 match = re.search( pattern, output )
4527 if match:
4528 return match.groupdict()[ 'value' ]
4529 else:
4530 main.log.error( self.name + ": transactionlMapGet did not" +
4531 " match expected output." )
4532 main.log.debug( self.name + " expected: " + pattern )
4533 main.log.debug( self.name + " actual: " + repr( output ) )
4534 return None
4535 except TypeError:
4536 main.log.exception( self.name + ": Object not as expected" )
4537 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004538 except Exception:
4539 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004540 main.cleanAndExit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004541
Jon Hall935db192016-04-19 00:22:04 -07004542 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004543 """
4544 CLI command to put a value into 'numKeys' number of keys in a
4545 consistent map using transactions. This a test function and can only
4546 put into keys named 'Key#' of the test map hard coded into the cli command
4547 Required arguments:
4548 numKeys - Number of keys to add the value to
4549 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004550 returns:
4551 A dictionary whose keys are the name of the keys put into the map
4552 and the values of the keys are dictionaries whose key-values are
4553 'value': value put into map and optionaly
4554 'oldValue': Previous value in the key or
4555 None on Error
4556
4557 Example output
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004558 { 'Key1': { 'oldValue': 'oldTestValue', 'value': 'Testing' },
4559 'Key2': { 'value': 'Testing' } }
Jon Hall2a5002c2015-08-21 16:49:11 -07004560 """
4561 try:
4562 numKeys = str( numKeys )
4563 value = str( value )
4564 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004565 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004566 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004567 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4568 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4569 results = {}
4570 for line in output.splitlines():
4571 new = re.search( newPattern, line )
4572 updated = re.search( updatedPattern, line )
4573 if new:
4574 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4575 elif updated:
4576 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004577 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004578 else:
4579 main.log.error( self.name + ": transactionlMapGet did not" +
4580 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004581 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4582 newPattern,
4583 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004584 main.log.debug( self.name + " actual: " + repr( output ) )
4585 return results
4586 except TypeError:
4587 main.log.exception( self.name + ": Object not as expected" )
4588 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004589 except Exception:
4590 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004591 main.cleanAndExit()
Jon Hallc6793552016-01-19 14:18:37 -08004592
acsmarsdaea66c2015-09-03 11:44:06 -07004593 def maps( self, jsonFormat=True ):
4594 """
4595 Description: Returns result of onos:maps
4596 Optional:
4597 * jsonFormat: enable json formatting of output
4598 """
4599 try:
4600 cmdStr = "maps"
4601 if jsonFormat:
4602 cmdStr += " -j"
4603 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004604 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004605 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004606 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004607 except AssertionError:
4608 main.log.exception( "" )
4609 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004610 except TypeError:
4611 main.log.exception( self.name + ": Object not as expected" )
4612 return None
4613 except pexpect.EOF:
4614 main.log.error( self.name + ": EOF exception found" )
4615 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004616 main.cleanAndExit()
acsmarsdaea66c2015-09-03 11:44:06 -07004617 except Exception:
4618 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004619 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004620
4621 def getSwController( self, uri, jsonFormat=True ):
4622 """
4623 Descrition: Gets the controller information from the device
4624 """
4625 try:
4626 cmd = "device-controllers "
4627 if jsonFormat:
4628 cmd += "-j "
4629 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004630 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004631 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004632 return response
Jon Hallc6793552016-01-19 14:18:37 -08004633 except AssertionError:
4634 main.log.exception( "" )
4635 return None
GlennRC050596c2015-11-18 17:06:41 -08004636 except TypeError:
4637 main.log.exception( self.name + ": Object not as expected" )
4638 return None
4639 except pexpect.EOF:
4640 main.log.error( self.name + ": EOF exception found" )
4641 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004642 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004643 except Exception:
4644 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004645 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004646
4647 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4648 """
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004649 Descrition: sets the controller( s ) for the specified device
GlennRC050596c2015-11-18 17:06:41 -08004650
4651 Parameters:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004652 Required: uri - String: The uri of the device( switch ).
GlennRC050596c2015-11-18 17:06:41 -08004653 ip - String or List: The ip address of the controller.
4654 This parameter can be formed in a couple of different ways.
4655 VALID:
4656 10.0.0.1 - just the ip address
4657 tcp:10.0.0.1 - the protocol and the ip address
4658 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4659 so that you can add controllers with different
4660 protocols and ports
4661 INVALID:
4662 10.0.0.1:6653 - this is not supported by ONOS
4663
4664 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4665 port - The port number.
4666 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4667
4668 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4669 """
4670 try:
4671 cmd = "device-setcontrollers"
4672
4673 if jsonFormat:
4674 cmd += " -j"
4675 cmd += " " + uri
4676 if isinstance( ip, str ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004677 ip = [ ip ]
GlennRC050596c2015-11-18 17:06:41 -08004678 for item in ip:
4679 if ":" in item:
4680 sitem = item.split( ":" )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004681 if len( sitem ) == 3:
GlennRC050596c2015-11-18 17:06:41 -08004682 cmd += " " + item
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004683 elif "." in sitem[ 1 ]:
4684 cmd += " {}:{}".format( item, port )
GlennRC050596c2015-11-18 17:06:41 -08004685 else:
4686 main.log.error( "Malformed entry: " + item )
4687 raise TypeError
4688 else:
4689 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004690 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004691 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004692 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004693 if "Error" in response:
4694 main.log.error( response )
4695 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004696 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004697 except AssertionError:
4698 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004699 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004700 except TypeError:
4701 main.log.exception( self.name + ": Object not as expected" )
4702 return main.FALSE
4703 except pexpect.EOF:
4704 main.log.error( self.name + ": EOF exception found" )
4705 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004706 main.cleanAndExit()
GlennRC050596c2015-11-18 17:06:41 -08004707 except Exception:
4708 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004709 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004710
4711 def removeDevice( self, device ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004712 """
GlennRC20fc6522015-12-23 23:26:57 -08004713 Description:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004714 Remove a device from ONOS by passing the uri of the device( s ).
GlennRC20fc6522015-12-23 23:26:57 -08004715 Parameters:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004716 device - ( str or list ) the id or uri of the device ex. "of:0000000000000001"
GlennRC20fc6522015-12-23 23:26:57 -08004717 Returns:
4718 Returns main.FALSE if an exception is thrown or an error is present
4719 in the response. Otherwise, returns main.TRUE.
4720 NOTE:
4721 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004722 """
GlennRC20fc6522015-12-23 23:26:57 -08004723 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004724 if isinstance( device, str ):
You Wang823f5022016-08-18 15:24:41 -07004725 deviceStr = device
4726 device = []
4727 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004728
4729 for d in device:
4730 time.sleep( 1 )
4731 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004732 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004733 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004734 if "Error" in response:
4735 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4736 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004737 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004738 except AssertionError:
4739 main.log.exception( "" )
4740 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004741 except TypeError:
4742 main.log.exception( self.name + ": Object not as expected" )
4743 return main.FALSE
4744 except pexpect.EOF:
4745 main.log.error( self.name + ": EOF exception found" )
4746 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004747 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004748 except Exception:
4749 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004750 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004751
4752 def removeHost( self, host ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004753 """
GlennRC20fc6522015-12-23 23:26:57 -08004754 Description:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004755 Remove a host from ONOS by passing the id of the host( s )
GlennRC20fc6522015-12-23 23:26:57 -08004756 Parameters:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004757 hostId - ( str or list ) the id or mac of the host ex. "00:00:00:00:00:01"
GlennRC20fc6522015-12-23 23:26:57 -08004758 Returns:
4759 Returns main.FALSE if an exception is thrown or an error is present
4760 in the response. Otherwise, returns main.TRUE.
4761 NOTE:
4762 If a host cannot be removed, then this function will return main.FALSE
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004763 """
GlennRC20fc6522015-12-23 23:26:57 -08004764 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004765 if isinstance( host, str ):
GlennRC20fc6522015-12-23 23:26:57 -08004766 host = list( host )
4767
4768 for h in host:
4769 time.sleep( 1 )
4770 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004771 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004772 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004773 if "Error" in response:
4774 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4775 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004776 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004777 except AssertionError:
4778 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004779 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004780 except TypeError:
4781 main.log.exception( self.name + ": Object not as expected" )
4782 return main.FALSE
4783 except pexpect.EOF:
4784 main.log.error( self.name + ": EOF exception found" )
4785 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004786 main.cleanAndExit()
GlennRC20fc6522015-12-23 23:26:57 -08004787 except Exception:
4788 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004789 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004790
YPZhangfebf7302016-05-24 16:45:56 -07004791 def link( self, begin, end, state, timeout=30, showResponse=True ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004792 """
GlennRCed771242016-01-13 17:02:47 -08004793 Description:
4794 Bring link down or up in the null-provider.
4795 params:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004796 begin - ( string ) One end of a device or switch.
4797 end - ( string ) the other end of the device or switch
GlennRCed771242016-01-13 17:02:47 -08004798 returns:
4799 main.TRUE if no exceptions were thrown and no Errors are
4800 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004801 """
GlennRCed771242016-01-13 17:02:47 -08004802 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004803 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07004804 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004805 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004806 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08004807 if "Error" in response or "Failure" in response:
4808 main.log.error( response )
4809 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004810 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004811 except AssertionError:
4812 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004813 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08004814 except TypeError:
4815 main.log.exception( self.name + ": Object not as expected" )
4816 return main.FALSE
4817 except pexpect.EOF:
4818 main.log.error( self.name + ": EOF exception found" )
4819 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004820 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004821 except Exception:
4822 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004823 main.cleanAndExit()
GlennRCed771242016-01-13 17:02:47 -08004824
Jon Hall2c8959e2016-12-16 12:17:34 -08004825 def portstate( self, dpid, port, state ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004826 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07004827 Description:
4828 Changes the state of port in an OF switch by means of the
4829 PORTSTATUS OF messages.
4830 params:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004831 dpid - ( string ) Datapath ID of the device. Ex: 'of:0000000000000102'
4832 port - ( string ) target port in the device. Ex: '2'
4833 state - ( string ) target state ( enable or disable )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004834 returns:
4835 main.TRUE if no exceptions were thrown and no Errors are
4836 present in the resoponse. Otherwise, returns main.FALSE
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004837 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07004838 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08004839 state = state.lower()
4840 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07004841 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004842 response = self.sendline( cmd, showResponse=True )
4843 assert response is not None, "Error in sendline"
4844 assert "Command not found:" not in response, response
4845 if "Error" in response or "Failure" in response:
4846 main.log.error( response )
4847 return main.FALSE
4848 return main.TRUE
4849 except AssertionError:
4850 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004851 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07004852 except TypeError:
4853 main.log.exception( self.name + ": Object not as expected" )
4854 return main.FALSE
4855 except pexpect.EOF:
4856 main.log.error( self.name + ": EOF exception found" )
4857 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004858 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004859 except Exception:
4860 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004861 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004862
4863 def logSet( self, level="INFO", app="org.onosproject" ):
4864 """
4865 Set the logging level to lvl for a specific app
4866 returns main.TRUE on success
4867 returns main.FALSE if Error occurred
4868 if noExit is True, TestON will not exit, but clean up
4869 Available level: DEBUG, TRACE, INFO, WARN, ERROR
4870 Level defaults to INFO
4871 """
4872 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004873 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07004874 self.handle.expect( "onos>" )
4875
4876 response = self.handle.before
4877 if re.search( "Error", response ):
4878 return main.FALSE
4879 return main.TRUE
4880 except pexpect.TIMEOUT:
4881 main.log.exception( self.name + ": TIMEOUT exception found" )
Devin Lim44075962017-08-11 10:56:37 -07004882 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004883 except pexpect.EOF:
4884 main.log.error( self.name + ": EOF exception found" )
4885 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07004886 main.cleanAndExit()
Flavio Castro82ee2f62016-06-07 15:04:12 -07004887 except Exception:
4888 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07004889 main.cleanAndExit()
You Wangdb8cd0a2016-05-26 15:19:45 -07004890
4891 def getGraphDict( self, timeout=60, includeHost=False ):
4892 """
4893 Return a dictionary which describes the latest network topology data as a
4894 graph.
4895 An example of the dictionary:
4896 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
4897 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
4898 Each vertex should at least have an 'edges' attribute which describes the
4899 adjacency information. The value of 'edges' attribute is also represented by
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004900 a dictionary, which maps each edge ( identified by the neighbor vertex ) to a
You Wangdb8cd0a2016-05-26 15:19:45 -07004901 list of attributes.
4902 An example of the edges dictionary:
4903 'edges': { vertex2: { 'port': ..., 'weight': ... },
4904 vertex3: { 'port': ..., 'weight': ... } }
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004905 If includeHost == True, all hosts ( and host-switch links ) will be included
You Wangdb8cd0a2016-05-26 15:19:45 -07004906 in topology data.
4907 """
4908 graphDict = {}
4909 try:
4910 links = self.links()
4911 links = json.loads( links )
4912 devices = self.devices()
4913 devices = json.loads( devices )
4914 idToDevice = {}
4915 for device in devices:
4916 idToDevice[ device[ 'id' ] ] = device
4917 if includeHost:
4918 hosts = self.hosts()
4919 # FIXME: support 'includeHost' argument
4920 for link in links:
4921 nodeA = link[ 'src' ][ 'device' ]
4922 nodeB = link[ 'dst' ][ 'device' ]
4923 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07004924 if nodeA not in graphDict.keys():
4925 graphDict[ nodeA ] = { 'edges': {},
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004926 'dpid': idToDevice[ nodeA ][ 'id' ][ 3: ],
Jon Halle0f0b342017-04-18 11:43:47 -07004927 'type': idToDevice[ nodeA ][ 'type' ],
4928 'available': idToDevice[ nodeA ][ 'available' ],
4929 'role': idToDevice[ nodeA ][ 'role' ],
4930 'mfr': idToDevice[ nodeA ][ 'mfr' ],
4931 'hw': idToDevice[ nodeA ][ 'hw' ],
4932 'sw': idToDevice[ nodeA ][ 'sw' ],
4933 'serial': idToDevice[ nodeA ][ 'serial' ],
4934 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004935 'annotations': idToDevice[ nodeA ][ 'annotations' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07004936 else:
4937 # Assert nodeB is not connected to any current links of nodeA
4938 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07004939 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
4940 'type': link[ 'type' ],
4941 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07004942 return graphDict
4943 except ( TypeError, ValueError ):
4944 main.log.exception( self.name + ": Object not as expected" )
4945 return None
4946 except KeyError:
4947 main.log.exception( self.name + ": KeyError exception found" )
4948 return None
4949 except AssertionError:
4950 main.log.exception( self.name + ": AssertionError exception found" )
4951 return None
4952 except pexpect.EOF:
4953 main.log.error( self.name + ": EOF exception found" )
4954 main.log.error( self.name + ": " + self.handle.before )
4955 return None
4956 except Exception:
4957 main.log.exception( self.name + ": Uncaught exception!" )
4958 return None
YPZhangcbc2a062016-07-11 10:55:44 -07004959
4960 def getIntentPerfSummary( self ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004961 """
YPZhangcbc2a062016-07-11 10:55:44 -07004962 Send command to check intent-perf summary
4963 Returns: dictionary for intent-perf summary
4964 if something wrong, function will return None
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004965 """
YPZhangcbc2a062016-07-11 10:55:44 -07004966 cmd = "intent-perf -s"
4967 respDic = {}
4968 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08004969 assert resp is not None, "Error in sendline"
4970 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07004971 try:
4972 # Generate the dictionary to return
4973 for l in resp.split( "\n" ):
4974 # Delete any white space in line
4975 temp = re.sub( r'\s+', '', l )
4976 temp = temp.split( ":" )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004977 respDic[ temp[ 0 ] ] = temp[ 1 ]
YPZhangcbc2a062016-07-11 10:55:44 -07004978
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07004979 except ( TypeError, ValueError ):
YPZhangcbc2a062016-07-11 10:55:44 -07004980 main.log.exception( self.name + ": Object not as expected" )
4981 return None
4982 except KeyError:
4983 main.log.exception( self.name + ": KeyError exception found" )
4984 return None
4985 except AssertionError:
4986 main.log.exception( self.name + ": AssertionError exception found" )
4987 return None
4988 except pexpect.EOF:
4989 main.log.error( self.name + ": EOF exception found" )
4990 main.log.error( self.name + ": " + self.handle.before )
4991 return None
4992 except Exception:
4993 main.log.exception( self.name + ": Uncaught exception!" )
4994 return None
4995 return respDic
4996
Chiyu Chengec63bde2016-11-17 18:11:36 -08004997 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07004998 """
4999 Searches the latest ONOS log file for the given search term and
5000 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005001
chengchiyu08303a02016-09-08 17:40:26 -07005002 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005003 searchTerm:
5004 The string to grep from the ONOS log.
5005 startLine:
5006 The term that decides which line is the start to search the searchTerm in
5007 the karaf log. For now, startTerm only works in 'first' mode.
5008 logNum:
5009 In some extreme cases, one karaf log is not big enough to contain all the
5010 information.Because of this, search mutiply logs is necessary to capture
5011 the right result. logNum is the number of karaf logs that we need to search
5012 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005013 mode:
5014 all: return all the strings that contain the search term
5015 last: return the last string that contains the search term
5016 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005017 num: return the number of times that the searchTerm appears in the log
5018 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005019 """
5020 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005021 assert isinstance( searchTerm, str )
Jon Halle0f0b342017-04-18 11:43:47 -07005022 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005023 logPath = '/opt/onos/log/karaf.log.'
5024 logPaths = '/opt/onos/log/karaf.log'
5025 for i in range( 1, logNum ):
5026 logPaths = logPath + str( i ) + " " + logPaths
5027 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005028 if startLine:
5029 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5030 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005031 if mode == 'all':
5032 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005033 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005034 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005035 elif mode == 'first':
5036 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5037 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005038 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005039 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005040 return num
You Wang6d301d42017-04-21 10:49:33 -07005041 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005042 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005043 return int( totalLines )
You Wang6d301d42017-04-21 10:49:33 -07005044 else:
5045 main.log.error( self.name + " unsupported mode" )
5046 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005047 before = self.sendline( cmd )
5048 before = before.splitlines()
5049 # make sure the returned list only contains the search term
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005050 returnLines = [ line for line in before if searchTerm in line ]
chengchiyu08303a02016-09-08 17:40:26 -07005051 return returnLines
5052 except AssertionError:
5053 main.log.error( self.name + " searchTerm is not string type" )
5054 return None
5055 except pexpect.EOF:
5056 main.log.error( self.name + ": EOF exception found" )
5057 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005058 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005059 except pexpect.TIMEOUT:
5060 main.log.error( self.name + ": TIMEOUT exception found" )
5061 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005062 main.cleanAndExit()
chengchiyu08303a02016-09-08 17:40:26 -07005063 except Exception:
5064 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005065 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005066
5067 def vplsShow( self, jsonFormat=True ):
5068 """
5069 Description: Returns result of onos:vpls show, which should list the
5070 configured VPLS networks and the assigned interfaces.
5071 Optional:
5072 * jsonFormat: enable json formatting of output
5073 Returns:
5074 The output of the command or None on error.
5075 """
5076 try:
5077 cmdStr = "vpls show"
5078 if jsonFormat:
5079 raise NotImplementedError
5080 cmdStr += " -j"
5081 handle = self.sendline( cmdStr )
5082 assert handle is not None, "Error in sendline"
5083 assert "Command not found:" not in handle, handle
5084 return handle
5085 except AssertionError:
5086 main.log.exception( "" )
5087 return None
5088 except TypeError:
5089 main.log.exception( self.name + ": Object not as expected" )
5090 return None
5091 except pexpect.EOF:
5092 main.log.error( self.name + ": EOF exception found" )
5093 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005094 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005095 except NotImplementedError:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005096 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005097 return None
5098 except Exception:
5099 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005100 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005101
5102 def parseVplsShow( self ):
5103 """
5104 Parse the cli output of 'vpls show' into json output. This is required
5105 as there is currently no json output available.
5106 """
5107 try:
5108 output = []
5109 raw = self.vplsShow( jsonFormat=False )
5110 namePat = "VPLS name: (?P<name>\w+)"
5111 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5112 encapPat = "Encapsulation: (?P<encap>\w+)"
5113 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5114 mIter = re.finditer( pattern, raw )
5115 for match in mIter:
5116 item = {}
5117 item[ 'name' ] = match.group( 'name' )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005118 ifaces = match.group( 'interfaces' ).split( ', ' )
Jon Hall2c8959e2016-12-16 12:17:34 -08005119 if ifaces == [ "" ]:
5120 ifaces = []
5121 item[ 'interfaces' ] = ifaces
5122 encap = match.group( 'encap' )
5123 if encap != 'NONE':
5124 item[ 'encapsulation' ] = encap.lower()
5125 output.append( item )
5126 return output
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 vplsList( self, jsonFormat=True ):
5132 """
5133 Description: Returns result of onos:vpls list, which should list the
5134 configured VPLS networks.
5135 Optional:
5136 * jsonFormat: enable json formatting of output
5137 """
5138 try:
5139 cmdStr = "vpls list"
5140 if jsonFormat:
5141 raise NotImplementedError
5142 cmdStr += " -j"
5143 handle = self.sendline( cmdStr )
5144 assert handle is not None, "Error in sendline"
5145 assert "Command not found:" not in handle, handle
5146 return handle
5147 except AssertionError:
5148 main.log.exception( "" )
5149 return None
5150 except TypeError:
5151 main.log.exception( self.name + ": Object not as expected" )
5152 return None
5153 except pexpect.EOF:
5154 main.log.error( self.name + ": EOF exception found" )
5155 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005156 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005157 except NotImplementedError:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005158 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005159 return None
5160 except Exception:
5161 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005162 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005163
5164 def vplsCreate( self, network ):
5165 """
5166 CLI command to create a new VPLS network.
5167 Required arguments:
5168 network - String name of the network to create.
5169 returns:
5170 main.TRUE on success and main.FALSE on failure
5171 """
5172 try:
5173 network = str( network )
5174 cmdStr = "vpls create "
5175 cmdStr += network
5176 output = self.sendline( cmdStr )
5177 assert output is not None, "Error in sendline"
5178 assert "Command not found:" not in output, output
5179 assert "Error executing command" not in output, output
5180 assert "VPLS already exists:" not in output, output
5181 return main.TRUE
5182 except AssertionError:
5183 main.log.exception( "" )
5184 return main.FALSE
5185 except TypeError:
5186 main.log.exception( self.name + ": Object not as expected" )
5187 return main.FALSE
5188 except pexpect.EOF:
5189 main.log.error( self.name + ": EOF exception found" )
5190 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005191 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005192 except Exception:
5193 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005194 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005195
5196 def vplsDelete( self, network ):
5197 """
5198 CLI command to delete a VPLS network.
5199 Required arguments:
5200 network - Name of the network to delete.
5201 returns:
5202 main.TRUE on success and main.FALSE on failure
5203 """
5204 try:
5205 network = str( network )
5206 cmdStr = "vpls delete "
5207 cmdStr += network
5208 output = self.sendline( cmdStr )
5209 assert output is not None, "Error in sendline"
5210 assert "Command not found:" not in output, output
5211 assert "Error executing command" not in output, output
5212 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005213 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005214 return main.TRUE
5215 except AssertionError:
5216 main.log.exception( "" )
5217 return main.FALSE
5218 except TypeError:
5219 main.log.exception( self.name + ": Object not as expected" )
5220 return main.FALSE
5221 except pexpect.EOF:
5222 main.log.error( self.name + ": EOF exception found" )
5223 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005224 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005225 except Exception:
5226 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005227 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005228
5229 def vplsAddIface( self, network, iface ):
5230 """
5231 CLI command to add an interface to a VPLS network.
5232 Required arguments:
5233 network - Name of the network to add the interface to.
5234 iface - The ONOS name for an interface.
5235 returns:
5236 main.TRUE on success and main.FALSE on failure
5237 """
5238 try:
5239 network = str( network )
5240 iface = str( iface )
5241 cmdStr = "vpls add-if "
5242 cmdStr += network + " " + iface
5243 output = self.sendline( cmdStr )
5244 assert output is not None, "Error in sendline"
5245 assert "Command not found:" not in output, output
5246 assert "Error executing command" not in output, output
5247 assert "already associated to network" not in output, output
5248 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005249 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005250 return main.TRUE
5251 except AssertionError:
5252 main.log.exception( "" )
5253 return main.FALSE
5254 except TypeError:
5255 main.log.exception( self.name + ": Object not as expected" )
5256 return main.FALSE
5257 except pexpect.EOF:
5258 main.log.error( self.name + ": EOF exception found" )
5259 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005260 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005261 except Exception:
5262 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005263 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005264
5265 def vplsRemIface( self, network, iface ):
5266 """
5267 CLI command to remove an interface from a VPLS network.
5268 Required arguments:
5269 network - Name of the network to remove the interface from.
5270 iface - Name of the interface to remove.
5271 returns:
5272 main.TRUE on success and main.FALSE on failure
5273 """
5274 try:
5275 iface = str( iface )
5276 cmdStr = "vpls rem-if "
5277 cmdStr += network + " " + iface
5278 output = self.sendline( cmdStr )
5279 assert output is not None, "Error in sendline"
5280 assert "Command not found:" not in output, output
5281 assert "Error executing command" not in output, output
5282 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005283 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005284 return main.TRUE
5285 except AssertionError:
5286 main.log.exception( "" )
5287 return main.FALSE
5288 except TypeError:
5289 main.log.exception( self.name + ": Object not as expected" )
5290 return main.FALSE
5291 except pexpect.EOF:
5292 main.log.error( self.name + ": EOF exception found" )
5293 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005294 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005295 except Exception:
5296 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005297 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005298
5299 def vplsClean( self ):
5300 """
5301 Description: Clears the VPLS app configuration.
5302 Returns: main.TRUE on success and main.FALSE on failure
5303 """
5304 try:
5305 cmdStr = "vpls clean"
5306 handle = self.sendline( cmdStr )
5307 assert handle is not None, "Error in sendline"
5308 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005309 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005310 return handle
5311 except AssertionError:
5312 main.log.exception( "" )
5313 return main.FALSE
5314 except TypeError:
5315 main.log.exception( self.name + ": Object not as expected" )
5316 return main.FALSE
5317 except pexpect.EOF:
5318 main.log.error( self.name + ": EOF exception found" )
5319 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005320 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005321 except Exception:
5322 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005323 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005324
5325 def vplsSetEncap( self, network, encapType ):
5326 """
5327 CLI command to add an interface to a VPLS network.
5328 Required arguments:
5329 network - Name of the network to create.
5330 encapType - Type of encapsulation.
5331 returns:
5332 main.TRUE on success and main.FALSE on failure
5333 """
5334 try:
5335 network = str( network )
5336 encapType = str( encapType ).upper()
5337 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5338 cmdStr = "vpls set-encap "
5339 cmdStr += network + " " + encapType
5340 output = self.sendline( cmdStr )
5341 assert output is not None, "Error in sendline"
5342 assert "Command not found:" not in output, output
5343 assert "Error executing command" not in output, output
5344 assert "already associated to network" not in output, output
5345 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005346 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005347 return main.TRUE
5348 except AssertionError:
5349 main.log.exception( "" )
5350 return main.FALSE
5351 except TypeError:
5352 main.log.exception( self.name + ": Object not as expected" )
5353 return main.FALSE
5354 except pexpect.EOF:
5355 main.log.error( self.name + ": EOF exception found" )
5356 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005357 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005358 except Exception:
5359 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005360 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005361
5362 def interfaces( self, jsonFormat=True ):
5363 """
5364 Description: Returns result of interfaces command.
5365 Optional:
5366 * jsonFormat: enable json formatting of output
5367 Returns:
5368 The output of the command or None on error.
5369 """
5370 try:
5371 cmdStr = "interfaces"
5372 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005373 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005374 cmdStr += " -j"
5375 handle = self.sendline( cmdStr )
5376 assert handle is not None, "Error in sendline"
5377 assert "Command not found:" not in handle, handle
5378 return handle
5379 except AssertionError:
5380 main.log.exception( "" )
5381 return None
5382 except TypeError:
5383 main.log.exception( self.name + ": Object not as expected" )
5384 return None
5385 except pexpect.EOF:
5386 main.log.error( self.name + ": EOF exception found" )
5387 main.log.error( self.name + ": " + self.handle.before )
Devin Lim44075962017-08-11 10:56:37 -07005388 main.cleanAndExit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005389 except NotImplementedError:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005390 main.log.exception( self.name + ": Json output not supported" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005391 return None
5392 except Exception:
5393 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005394 main.cleanAndExit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005395
5396 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005397 """
Chiyu Chengec63bde2016-11-17 18:11:36 -08005398 Get the timestamp of searchTerm from karaf log.
5399
5400 Arguments:
5401 splitTerm_before and splitTerm_after:
5402
5403 The terms that split the string that contains the timeStamp of
5404 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5405 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5406 and the splitTerm_after is "x"
5407
5408 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005409 Please look at the "logsearch" Function in onosclidriver.py
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005410 """
Chiyu Chengec63bde2016-11-17 18:11:36 -08005411 if logNum < 0:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005412 main.log.error( "Get wrong log number " )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005413 return main.ERROR
5414 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005415 if len( lines ) == 0:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005416 main.log.warn( "Captured timestamp string is empty" )
5417 return main.ERROR
5418 lines = lines[ 0 ]
5419 try:
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005420 assert isinstance( lines, str )
Chiyu Chengec63bde2016-11-17 18:11:36 -08005421 # get the target value
5422 line = lines.split( splitTerm_before )
5423 key = line[ 1 ].split( splitTerm_after )
5424 return int( key[ 0 ] )
5425 except IndexError:
5426 main.log.warn( "Index Error!" )
5427 return main.ERROR
5428 except AssertionError:
5429 main.log.warn( "Search Term Not Found " )
5430 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005431
5432 def workQueueAdd( self, queueName, value ):
5433 """
5434 CLI command to add a string to the specified Work Queue.
5435 This function uses the distributed primitives test app, which
5436 gives some cli access to distributed primitives for testing
5437 purposes only.
5438
5439 Required arguments:
5440 queueName - The name of the queue to add to
5441 value - The value to add to the queue
5442 returns:
5443 main.TRUE on success, main.FALSE on failure and
5444 main.ERROR on error.
5445 """
5446 try:
5447 queueName = str( queueName )
5448 value = str( value )
5449 prefix = "work-queue-test"
5450 operation = "add"
5451 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5452 output = self.distPrimitivesSend( cmdStr )
5453 if "Invalid operation name" in output:
5454 main.log.warn( output )
5455 return main.ERROR
5456 elif "Done" in output:
5457 return main.TRUE
5458 except TypeError:
5459 main.log.exception( self.name + ": Object not as expected" )
5460 return main.ERROR
5461 except Exception:
5462 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005463 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005464
5465 def workQueueAddMultiple( self, queueName, value1, value2 ):
5466 """
5467 CLI command to add two strings to the specified Work Queue.
5468 This function uses the distributed primitives test app, which
5469 gives some cli access to distributed primitives for testing
5470 purposes only.
5471
5472 Required arguments:
5473 queueName - The name of the queue to add to
5474 value1 - The first value to add to the queue
5475 value2 - The second value to add to the queue
5476 returns:
5477 main.TRUE on success, main.FALSE on failure and
5478 main.ERROR on error.
5479 """
5480 try:
5481 queueName = str( queueName )
5482 value1 = str( value1 )
5483 value2 = str( value2 )
5484 prefix = "work-queue-test"
5485 operation = "addMultiple"
5486 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5487 output = self.distPrimitivesSend( cmdStr )
5488 if "Invalid operation name" in output:
5489 main.log.warn( output )
5490 return main.ERROR
5491 elif "Done" in output:
5492 return main.TRUE
5493 except TypeError:
5494 main.log.exception( self.name + ": Object not as expected" )
5495 return main.ERROR
5496 except Exception:
5497 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005498 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005499
5500 def workQueueTakeAndComplete( self, queueName, number=1 ):
5501 """
5502 CLI command to take a value from the specified Work Queue and compelte it.
5503 This function uses the distributed primitives test app, which
5504 gives some cli access to distributed primitives for testing
5505 purposes only.
5506
5507 Required arguments:
5508 queueName - The name of the queue to add to
5509 number - The number of items to take and complete
5510 returns:
5511 main.TRUE on success, main.FALSE on failure and
5512 main.ERROR on error.
5513 """
5514 try:
5515 queueName = str( queueName )
5516 number = str( int( number ) )
5517 prefix = "work-queue-test"
5518 operation = "takeAndComplete"
5519 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5520 output = self.distPrimitivesSend( cmdStr )
5521 if "Invalid operation name" in output:
5522 main.log.warn( output )
5523 return main.ERROR
5524 elif "Done" in output:
5525 return main.TRUE
5526 except TypeError:
5527 main.log.exception( self.name + ": Object not as expected" )
5528 return main.ERROR
5529 except Exception:
5530 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005531 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005532
5533 def workQueueDestroy( self, queueName ):
5534 """
5535 CLI command to destroy the specified Work Queue.
5536 This function uses the distributed primitives test app, which
5537 gives some cli access to distributed primitives for testing
5538 purposes only.
5539
5540 Required arguments:
5541 queueName - The name of the queue to add to
5542 returns:
5543 main.TRUE on success, main.FALSE on failure and
5544 main.ERROR on error.
5545 """
5546 try:
5547 queueName = str( queueName )
5548 prefix = "work-queue-test"
5549 operation = "destroy"
5550 cmdStr = " ".join( [ prefix, queueName, operation ] )
5551 output = self.distPrimitivesSend( cmdStr )
5552 if "Invalid operation name" in output:
5553 main.log.warn( output )
5554 return main.ERROR
5555 return main.TRUE
5556 except TypeError:
5557 main.log.exception( self.name + ": Object not as expected" )
5558 return main.ERROR
5559 except Exception:
5560 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005561 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005562
5563 def workQueueTotalPending( self, queueName ):
5564 """
5565 CLI command to get the Total Pending items of the specified Work Queue.
5566 This function uses the distributed primitives test app, which
5567 gives some cli access to distributed primitives for testing
5568 purposes only.
5569
5570 Required arguments:
5571 queueName - The name of the queue to add to
5572 returns:
5573 The number of Pending items in the specified work queue or
5574 None on error
5575 """
5576 try:
5577 queueName = str( queueName )
5578 prefix = "work-queue-test"
5579 operation = "totalPending"
5580 cmdStr = " ".join( [ prefix, queueName, operation ] )
5581 output = self.distPrimitivesSend( cmdStr )
5582 pattern = r'\d+'
5583 if "Invalid operation name" in output:
5584 main.log.warn( output )
5585 return None
5586 else:
5587 match = re.search( pattern, output )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005588 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005589 except ( AttributeError, TypeError ):
5590 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5591 return None
5592 except Exception:
5593 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005594 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005595
5596 def workQueueTotalCompleted( self, queueName ):
5597 """
5598 CLI command to get the Total Completed items of the specified Work Queue.
5599 This function uses the distributed primitives test app, which
5600 gives some cli access to distributed primitives for testing
5601 purposes only.
5602
5603 Required arguments:
5604 queueName - The name of the queue to add to
5605 returns:
5606 The number of complete items in the specified work queue or
5607 None on error
5608 """
5609 try:
5610 queueName = str( queueName )
5611 prefix = "work-queue-test"
5612 operation = "totalCompleted"
5613 cmdStr = " ".join( [ prefix, queueName, operation ] )
5614 output = self.distPrimitivesSend( cmdStr )
5615 pattern = r'\d+'
5616 if "Invalid operation name" in output:
5617 main.log.warn( output )
5618 return None
5619 else:
5620 match = re.search( pattern, output )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005621 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005622 except ( AttributeError, TypeError ):
5623 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5624 return None
5625 except Exception:
5626 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005627 main.cleanAndExit()
Jon Halle0f0b342017-04-18 11:43:47 -07005628
5629 def workQueueTotalInProgress( self, queueName ):
5630 """
5631 CLI command to get the Total In Progress items of the specified Work Queue.
5632 This function uses the distributed primitives test app, which
5633 gives some cli access to distributed primitives for testing
5634 purposes only.
5635
5636 Required arguments:
5637 queueName - The name of the queue to add to
5638 returns:
5639 The number of In Progress items in the specified work queue or
5640 None on error
5641 """
5642 try:
5643 queueName = str( queueName )
5644 prefix = "work-queue-test"
5645 operation = "totalInProgress"
5646 cmdStr = " ".join( [ prefix, queueName, operation ] )
5647 output = self.distPrimitivesSend( cmdStr )
5648 pattern = r'\d+'
5649 if "Invalid operation name" in output:
5650 main.log.warn( output )
5651 return None
5652 else:
5653 match = re.search( pattern, output )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005654 return match.group( 0 )
Jon Halle0f0b342017-04-18 11:43:47 -07005655 except ( AttributeError, TypeError ):
5656 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5657 return None
5658 except Exception:
5659 main.log.exception( self.name + ": Uncaught exception!" )
Devin Lim44075962017-08-11 10:56:37 -07005660 main.cleanAndExit()
Jeremy Ronquillo818bc7c2017-08-09 17:14:53 +00005661
5662 def events( self, args='-a' ):
5663 """
5664 Description: Returns events -a command output
5665 Optional:
5666 add other arguments
5667 """
5668 try:
5669 cmdStr = "events"
5670 if args:
5671 cmdStr += " " + args
5672 handle = self.sendline( cmdStr )
5673 assert handle is not None, "Error in sendline"
5674 assert "Command not found:" not in handle, handle
5675 return handle
5676 except AssertionError:
5677 main.log.exception( "" )
5678 return None
5679 except TypeError:
5680 main.log.exception( self.name + ": Object not as expected" )
5681 return None
5682 except pexpect.EOF:
5683 main.log.error( self.name + ": EOF exception found" )
5684 main.log.error( self.name + ": " + self.handle.before )
5685 main.cleanAndExit()
5686 except Exception:
5687 main.log.exception( self.name + ": Uncaught exception!" )
5688 main.cleanAndExit()
5689
5690 def getMaster( self, deviceID ):
5691 """
5692 Description: Obtains current master using "roles" command for a specific deviceID
5693 """
5694 try:
5695 return str( self.getRole( deviceID )[ 'master' ] )
5696 except AssertionError:
5697 main.log.exception( "" )
5698 return None
5699 except TypeError:
5700 main.log.exception( self.name + ": Object not as expected" )
5701 return None
5702 except pexpect.EOF:
5703 main.log.error( self.name + ": EOF exception found" )
5704 main.log.error( self.name + ": " + self.handle.before )
5705 main.cleanAndExit()
5706 except Exception:
5707 main.log.exception( self.name + ": Uncaught exception!" )
Jeremy Ronquillo23fb2162017-09-15 14:59:57 -07005708 main.cleanAndExit()