blob: ac33201a2ba32d787151d92f41c4e11c5a92fce2 [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
5Copyright 2014 Open Networking Foundation (ONF)
6
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
14 (at your option) any later version.
15
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"""
24
25"""
andrewonlab95ce8322014-10-13 14:12:04 -040026This driver enters the onos> prompt to issue commands.
27
kelvin8ec71442015-01-15 16:57:00 -080028Please follow the coding style demonstrated by existing
andrewonlab95ce8322014-10-13 14:12:04 -040029functions and document properly.
30
31If you are a contributor to the driver, please
32list your email here for future contact:
33
34jhall@onlab.us
35andrew@onlab.us
Jon Halle8217482014-10-17 13:49:14 -040036shreya@onlab.us
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
kelvin8ec71442015-01-15 16:57:00 -080049class OnosCliDriver( CLI ):
andrewonlab95ce8322014-10-13 14:12:04 -040050
kelvin8ec71442015-01-15 16:57:00 -080051 def __init__( self ):
52 """
53 Initialize client
54 """
Jon Hallefbd9792015-03-05 16:11:36 -080055 self.name = None
56 self.home = None
57 self.handle = None
Devin Limdc78e202017-06-09 18:30:07 -070058 self.karafUser = None
59 self.karafPass = None
You Wangdb8cd0a2016-05-26 15:19:45 -070060 self.graph = Graph()
Devin Limdc78e202017-06-09 18:30:07 -070061 super( OnosCliDriver, self ).__init__()
kelvin8ec71442015-01-15 16:57:00 -080062
Devin Limdc78e202017-06-09 18:30:07 -070063 def checkOptions(self, var, defaultVar):
64 if var is None or var == "":
65 return defaultVar
66 return var
kelvin8ec71442015-01-15 16:57:00 -080067 def connect( self, **connectargs ):
68 """
andrewonlab95ce8322014-10-13 14:12:04 -040069 Creates ssh handle for ONOS cli.
kelvin8ec71442015-01-15 16:57:00 -080070 """
andrewonlab95ce8322014-10-13 14:12:04 -040071 try:
72 for key in connectargs:
kelvin8ec71442015-01-15 16:57:00 -080073 vars( self )[ key ] = connectargs[ key ]
andrew@onlab.us658ec012015-03-11 15:13:09 -070074 self.home = "~/onos"
andrewonlab95ce8322014-10-13 14:12:04 -040075 for key in self.options:
76 if key == "home":
Devin Limdc78e202017-06-09 18:30:07 -070077 self.home = self.options[ key ]
78 elif key == "karaf_username":
79 self.karafUser = self.options[ key ]
80 elif key == "karaf_password":
81 self.karafPass = self.options[ key ]
82
83 self.home = self.checkOptions(self.home, "~/onos")
84 self.karafUser = self.checkOptions(self.karafUser, self.user_name)
85 self.karafPass = self.checkOptions(self.karafPass, self.pwd )
andrewonlab95ce8322014-10-13 14:12:04 -040086
kelvin-onlaba4074292015-07-09 15:19:49 -070087 for key in self.options:
88 if key == 'onosIp':
89 self.onosIp = self.options[ 'onosIp' ]
90 break
91
kelvin8ec71442015-01-15 16:57:00 -080092 self.name = self.options[ 'name' ]
kelvin-onlaba4074292015-07-09 15:19:49 -070093
94 try:
Jon Hallc6793552016-01-19 14:18:37 -080095 if os.getenv( str( self.ip_address ) ) is not None:
kelvin-onlaba4074292015-07-09 15:19:49 -070096 self.ip_address = os.getenv( str( self.ip_address ) )
97 else:
98 main.log.info( self.name +
99 ": Trying to connect to " +
100 self.ip_address )
101
102 except KeyError:
103 main.log.info( "Invalid host name," +
104 " connecting to local host instead" )
105 self.ip_address = 'localhost'
106 except Exception as inst:
107 main.log.error( "Uncaught exception: " + str( inst ) )
108
kelvin8ec71442015-01-15 16:57:00 -0800109 self.handle = super( OnosCliDriver, self ).connect(
kelvin-onlab08679eb2015-01-21 16:11:48 -0800110 user_name=self.user_name,
111 ip_address=self.ip_address,
kelvin-onlab898a6c62015-01-16 14:13:53 -0800112 port=self.port,
113 pwd=self.pwd,
114 home=self.home )
andrewonlab95ce8322014-10-13 14:12:04 -0400115
kelvin8ec71442015-01-15 16:57:00 -0800116 self.handle.sendline( "cd " + self.home )
Devin Limdc78e202017-06-09 18:30:07 -0700117 self.handle.expect( self.prompt )
andrewonlab95ce8322014-10-13 14:12:04 -0400118 if self.handle:
119 return self.handle
kelvin8ec71442015-01-15 16:57:00 -0800120 else:
121 main.log.info( "NO ONOS HANDLE" )
andrewonlab95ce8322014-10-13 14:12:04 -0400122 return main.FALSE
Jon Halld4d4b372015-01-28 16:02:41 -0800123 except TypeError:
124 main.log.exception( self.name + ": Object not as expected" )
125 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400126 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800127 main.log.error( self.name + ": EOF exception found" )
128 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400129 main.cleanup()
130 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800131 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800132 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400133 main.cleanup()
134 main.exit()
135
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
167 main.FALSE on timeout (not guranteed you are disconnected)
168 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 )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500208 main.cleanup()
209 main.exit()
Jon Hall61282e32015-03-19 11:34:11 -0700210 except ValueError:
Jon Hall5aa168b2015-03-23 14:23:09 -0700211 main.log.error( self.name +
212 "ValueError exception in logout method" )
Jon Hallfebb1c72015-03-05 13:30:09 -0800213 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800214 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab38d2b4a2014-11-13 16:28:47 -0500215 main.cleanup()
216 main.exit()
217
kelvin-onlabd3b64892015-01-20 13:26:24 -0800218 def setCell( self, cellname ):
kelvin8ec71442015-01-15 16:57:00 -0800219 """
andrewonlab95ce8322014-10-13 14:12:04 -0400220 Calls 'cell <name>' to set the environment variables on ONOSbench
kelvin8ec71442015-01-15 16:57:00 -0800221
andrewonlab95ce8322014-10-13 14:12:04 -0400222 Before issuing any cli commands, set the environment variable first.
kelvin8ec71442015-01-15 16:57:00 -0800223 """
andrewonlab95ce8322014-10-13 14:12:04 -0400224 try:
225 if not cellname:
kelvin8ec71442015-01-15 16:57:00 -0800226 main.log.error( "Must define cellname" )
andrewonlab95ce8322014-10-13 14:12:04 -0400227 main.cleanup()
228 main.exit()
229 else:
kelvin8ec71442015-01-15 16:57:00 -0800230 self.handle.sendline( "cell " + str( cellname ) )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800231 # Expect the cellname in the ONOSCELL variable.
kelvin8ec71442015-01-15 16:57:00 -0800232 # Note that this variable name is subject to change
andrewonlab95ce8322014-10-13 14:12:04 -0400233 # and that this driver will have to change accordingly
Cameron Franke9c94fb02015-01-21 10:20:20 -0800234 self.handle.expect(str(cellname))
andrew@onlab.usc400b112015-01-21 15:33:19 -0800235 handleBefore = self.handle.before
236 handleAfter = self.handle.after
kelvin8ec71442015-01-15 16:57:00 -0800237 # Get the rest of the handle
Cameron Franke9c94fb02015-01-21 10:20:20 -0800238 self.handle.sendline("")
Devin Limdc78e202017-06-09 18:30:07 -0700239 self.handle.expect(self.prompt)
andrew@onlab.usc400b112015-01-21 15:33:19 -0800240 handleMore = self.handle.before
andrewonlab95ce8322014-10-13 14:12:04 -0400241
kelvin-onlabd3b64892015-01-20 13:26:24 -0800242 main.log.info( "Cell call returned: " + handleBefore +
243 handleAfter + handleMore )
andrewonlab95ce8322014-10-13 14:12:04 -0400244
245 return main.TRUE
246
Jon Halld4d4b372015-01-28 16:02:41 -0800247 except TypeError:
248 main.log.exception( self.name + ": Object not as expected" )
249 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400250 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800251 main.log.error( self.name + ": eof exception found" )
252 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400253 main.cleanup()
254 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800255 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800256 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400257 main.cleanup()
258 main.exit()
kelvin8ec71442015-01-15 16:57:00 -0800259
pingping-lin57a56ce2015-05-20 16:43:48 -0700260 def startOnosCli( self, ONOSIp, karafTimeout="",
Chiyu Chengef109502016-11-21 15:51:38 -0800261 commandlineTimeout=10, onosStartTimeout=60, waitForStart=False ):
kelvin8ec71442015-01-15 16:57:00 -0800262 """
Jon Hallefbd9792015-03-05 16:11:36 -0800263 karafTimeout is an optional argument. karafTimeout value passed
kelvin-onlabd3b64892015-01-20 13:26:24 -0800264 by user would be used to set the current karaf shell idle timeout.
265 Note that when ever this property is modified the shell will exit and
Hari Krishnad7b9c202015-01-05 10:38:14 -0800266 the subsequent login would reflect new idle timeout.
kelvin-onlabd3b64892015-01-20 13:26:24 -0800267 Below is an example to start a session with 60 seconds idle timeout
268 ( input value is in milliseconds ):
kelvin8ec71442015-01-15 16:57:00 -0800269
Hari Krishna25d42f72015-01-05 15:08:28 -0800270 tValue = "60000"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800271 main.ONOScli1.startOnosCli( ONOSIp, karafTimeout=tValue )
kelvin8ec71442015-01-15 16:57:00 -0800272
kelvin-onlabd3b64892015-01-20 13:26:24 -0800273 Note: karafTimeout is left as str so that this could be read
274 and passed to startOnosCli from PARAMS file as str.
kelvin8ec71442015-01-15 16:57:00 -0800275 """
You Wangf69ab392016-01-26 16:34:38 -0800276 self.onosIp = ONOSIp
andrewonlab95ce8322014-10-13 14:12:04 -0400277 try:
Jon Hall67253832016-12-05 09:47:13 -0800278 # Check if we are already in the cli
kelvin8ec71442015-01-15 16:57:00 -0800279 self.handle.sendline( "" )
280 x = self.handle.expect( [
Devin Limdc78e202017-06-09 18:30:07 -0700281 self.prompt, "onos>" ], commandlineTimeout)
andrewonlab48829f62014-11-17 13:49:01 -0500282 if x == 1:
kelvin8ec71442015-01-15 16:57:00 -0800283 main.log.info( "ONOS cli is already running" )
andrewonlab48829f62014-11-17 13:49:01 -0500284 return main.TRUE
andrewonlab95ce8322014-10-13 14:12:04 -0400285
Jon Hall67253832016-12-05 09:47:13 -0800286 # Not in CLI so login
Chiyu Chengef109502016-11-21 15:51:38 -0800287 if waitForStart:
288 # Wait for onos start ( -w ) and enter onos cli
289 startCliCommand = "onos -w "
290 else:
291 startCliCommand = "onos "
292 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800293 i = self.handle.expect( [
294 "onos>",
pingping-lin57a56ce2015-05-20 16:43:48 -0700295 pexpect.TIMEOUT ], onosStartTimeout )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400296
297 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800298 main.log.info( str( ONOSIp ) + " CLI Started successfully" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800299 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800300 self.handle.sendline(
Hari Krishnaac4e1782015-01-26 12:09:12 -0800301 "config:property-set -p org.apache.karaf.shell\
302 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800303 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700304 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800305 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800306 self.handle.expect( "onos>" )
andrewonlab2a7ea9b2014-10-24 12:21:05 -0400307 return main.TRUE
308 else:
kelvin8ec71442015-01-15 16:57:00 -0800309 # If failed, send ctrl+c to process and try again
310 main.log.info( "Starting CLI failed. Retrying..." )
311 self.handle.send( "\x03" )
Chiyu Chengef109502016-11-21 15:51:38 -0800312 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800313 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
314 timeout=30 )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400315 if i == 0:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800316 main.log.info( str( ONOSIp ) + " CLI Started " +
kelvin8ec71442015-01-15 16:57:00 -0800317 "successfully after retry attempt" )
Hari Krishnae36ef212015-01-04 14:09:13 -0800318 if karafTimeout:
kelvin8ec71442015-01-15 16:57:00 -0800319 self.handle.sendline(
kelvin-onlabd3b64892015-01-20 13:26:24 -0800320 "config:property-set -p org.apache.karaf.shell\
321 sshIdleTimeout " +
kelvin8ec71442015-01-15 16:57:00 -0800322 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700323 self.handle.expect( self.prompt )
Chiyu Chengef109502016-11-21 15:51:38 -0800324 self.handle.sendline( startCliCommand + str( ONOSIp ) )
kelvin8ec71442015-01-15 16:57:00 -0800325 self.handle.expect( "onos>" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400326 return main.TRUE
327 else:
kelvin8ec71442015-01-15 16:57:00 -0800328 main.log.error( "Connection to CLI " +
kelvin-onlabd3b64892015-01-20 13:26:24 -0800329 str( ONOSIp ) + " timeout" )
andrewonlab3a7c3c72014-10-24 17:21:03 -0400330 return main.FALSE
andrewonlab95ce8322014-10-13 14:12:04 -0400331
Jon Halld4d4b372015-01-28 16:02:41 -0800332 except TypeError:
333 main.log.exception( self.name + ": Object not as expected" )
334 return None
andrewonlab95ce8322014-10-13 14:12:04 -0400335 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800336 main.log.error( self.name + ": EOF exception found" )
337 main.log.error( self.name + ": " + self.handle.before )
andrewonlab95ce8322014-10-13 14:12:04 -0400338 main.cleanup()
339 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800340 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800341 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -0400342 main.cleanup()
343 main.exit()
344
suibin zhang116647a2016-05-06 16:30:09 -0700345 def startCellCli( self, karafTimeout="",
346 commandlineTimeout=10, onosStartTimeout=60 ):
347 """
348 Start CLI on onos ecll handle.
349
350 karafTimeout is an optional argument. karafTimeout value passed
351 by user would be used to set the current karaf shell idle timeout.
352 Note that when ever this property is modified the shell will exit and
353 the subsequent login would reflect new idle timeout.
354 Below is an example to start a session with 60 seconds idle timeout
355 ( input value is in milliseconds ):
356
357 tValue = "60000"
358
359 Note: karafTimeout is left as str so that this could be read
360 and passed to startOnosCli from PARAMS file as str.
361 """
362
363 try:
364 self.handle.sendline( "" )
365 x = self.handle.expect( [
Devin Limdc78e202017-06-09 18:30:07 -0700366 self.prompt, "onos>" ], commandlineTimeout)
suibin zhang116647a2016-05-06 16:30:09 -0700367
368 if x == 1:
369 main.log.info( "ONOS cli is already running" )
370 return main.TRUE
371
372 # Wait for onos start ( -w ) and enter onos cli
373 self.handle.sendline( "/opt/onos/bin/onos" )
374 i = self.handle.expect( [
375 "onos>",
376 pexpect.TIMEOUT ], onosStartTimeout )
377
378 if i == 0:
379 main.log.info( self.name + " CLI Started successfully" )
380 if karafTimeout:
381 self.handle.sendline(
382 "config:property-set -p org.apache.karaf.shell\
383 sshIdleTimeout " +
384 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700385 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700386 self.handle.sendline( "/opt/onos/bin/onos" )
387 self.handle.expect( "onos>" )
388 return main.TRUE
389 else:
390 # If failed, send ctrl+c to process and try again
391 main.log.info( "Starting CLI failed. Retrying..." )
392 self.handle.send( "\x03" )
393 self.handle.sendline( "/opt/onos/bin/onos" )
394 i = self.handle.expect( [ "onos>", pexpect.TIMEOUT ],
395 timeout=30 )
396 if i == 0:
397 main.log.info( self.name + " CLI Started " +
398 "successfully after retry attempt" )
399 if karafTimeout:
400 self.handle.sendline(
401 "config:property-set -p org.apache.karaf.shell\
402 sshIdleTimeout " +
403 karafTimeout )
Devin Limdc78e202017-06-09 18:30:07 -0700404 self.handle.expect( self.prompt )
suibin zhang116647a2016-05-06 16:30:09 -0700405 self.handle.sendline( "/opt/onos/bin/onos" )
406 self.handle.expect( "onos>" )
407 return main.TRUE
408 else:
409 main.log.error( "Connection to CLI " +
410 self.name + " timeout" )
411 return main.FALSE
412
413 except TypeError:
414 main.log.exception( self.name + ": Object not as expected" )
415 return None
416 except pexpect.EOF:
417 main.log.error( self.name + ": EOF exception found" )
418 main.log.error( self.name + ": " + self.handle.before )
419 main.cleanup()
420 main.exit()
421 except Exception:
422 main.log.exception( self.name + ": Uncaught exception!" )
423 main.cleanup()
424 main.exit()
425
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800426 def log( self, cmdStr, level="", noExit=False ):
kelvin-onlab9f541032015-02-04 16:19:53 -0800427 """
428 log the commands in the onos CLI.
kelvin-onlab338f5512015-02-06 10:53:16 -0800429 returns main.TRUE on success
Jon Hallefbd9792015-03-05 16:11:36 -0800430 returns main.FALSE if Error occurred
YPZhangebf9eb52016-05-12 15:20:24 -0700431 if noExit is True, TestON will not exit, but clean up
kelvin-onlab338f5512015-02-06 10:53:16 -0800432 Available level: DEBUG, TRACE, INFO, WARN, ERROR
433 Level defaults to INFO
Pratik Parab3b2ab5a2017-02-14 13:15:14 -0800434 if cmdStr has spaces then put quotes in the passed string
kelvin-onlab9f541032015-02-04 16:19:53 -0800435 """
436 try:
kelvin-onlab338f5512015-02-06 10:53:16 -0800437 lvlStr = ""
438 if level:
439 lvlStr = "--level=" + level
440
kelvin-onlab338f5512015-02-06 10:53:16 -0800441 self.handle.sendline( "log:log " + lvlStr + " " + cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -0700442 self.handle.expect( "log:log" )
kelvin-onlab9f541032015-02-04 16:19:53 -0800443 self.handle.expect( "onos>" )
kelvin-onlabfb521662015-02-27 09:52:40 -0800444
kelvin-onlab9f541032015-02-04 16:19:53 -0800445 response = self.handle.before
446 if re.search( "Error", response ):
447 return main.FALSE
448 return main.TRUE
Jon Hall80daded2015-05-27 16:07:00 -0700449 except pexpect.TIMEOUT:
450 main.log.exception( self.name + ": TIMEOUT exception found" )
YPZhangebf9eb52016-05-12 15:20:24 -0700451 if noExit:
452 main.cleanup()
453 return None
454 else:
455 main.cleanup()
456 main.exit()
kelvin-onlab9f541032015-02-04 16:19:53 -0800457 except pexpect.EOF:
458 main.log.error( self.name + ": EOF exception found" )
459 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700460 if noExit:
461 main.cleanup()
462 return None
463 else:
464 main.cleanup()
465 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800466 except Exception:
kelvin-onlabfb521662015-02-27 09:52:40 -0800467 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700468 if noExit:
469 main.cleanup()
470 return None
471 else:
472 main.cleanup()
473 main.exit()
andrewonlab95ce8322014-10-13 14:12:04 -0400474
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700475 def sendline( self, cmdStr, showResponse=False, debug=False, timeout=10, noExit=False, dollarSign=False ):
kelvin8ec71442015-01-15 16:57:00 -0800476 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800477 Send a completely user specified string to
478 the onos> prompt. Use this function if you have
andrewonlaba18f6bf2014-10-13 19:31:54 -0400479 a very specific command to send.
Jon Halle3f39ff2015-01-13 11:50:53 -0800480
YPZhang14a4aa92016-07-15 13:37:15 -0700481 if noExit is True, TestON will not exit, and return None
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700482 if dollarSign is True, TestON will not expect for '$' as a new CLI or onos> prompt
483 since '$' can be in the output.
YPZhangebf9eb52016-05-12 15:20:24 -0700484
andrewonlaba18f6bf2014-10-13 19:31:54 -0400485 Warning: There are no sanity checking to commands
486 sent using this method.
GlennRCed771242016-01-13 17:02:47 -0800487
kelvin8ec71442015-01-15 16:57:00 -0800488 """
andrewonlaba18f6bf2014-10-13 19:31:54 -0400489 try:
Jon Halla495f562016-05-16 18:03:26 -0700490 # Try to reconnect if disconnected from cli
491 self.handle.sendline( "" )
Devin Limdc78e202017-06-09 18:30:07 -0700492 i = self.handle.expect( [ "onos>", self.prompt, pexpect.TIMEOUT ] )
Jon Halla495f562016-05-16 18:03:26 -0700493 if i == 1:
494 main.log.error( self.name + ": onos cli session closed. ")
495 if self.onosIp:
496 main.log.warn( "Trying to reconnect " + self.onosIp )
497 reconnectResult = self.startOnosCli( self.onosIp )
498 if reconnectResult:
499 main.log.info( self.name + ": onos cli session reconnected." )
500 else:
501 main.log.error( self.name + ": reconnection failed." )
YPZhang14a4aa92016-07-15 13:37:15 -0700502 if noExit:
503 return None
504 else:
505 main.cleanup()
506 main.exit()
Jon Halla495f562016-05-16 18:03:26 -0700507 else:
508 main.cleanup()
509 main.exit()
510 if i == 2:
Jon Hall7a6ebfd2017-03-13 10:58:58 -0700511 main.log.warn( "Timeout when testing cli responsiveness" )
512 main.log.debug( self.handle.before )
513 self.handle.send( "\x03" ) # Send ctrl-c to clear previous output
Jon Halla495f562016-05-16 18:03:26 -0700514 self.handle.expect( "onos>" )
515
Jon Hall14a03b52016-05-11 12:07:30 -0700516 if debug:
517 # NOTE: This adds and average of .4 seconds per call
518 logStr = "\"Sending CLI command: '" + cmdStr + "'\""
Jon Halle0f0b342017-04-18 11:43:47 -0700519 self.log( logStr, noExit=noExit )
kelvin-onlabd3b64892015-01-20 13:26:24 -0800520 self.handle.sendline( cmdStr )
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -0700521 if dollarSign:
522 i = self.handle.expect( ["onos>"], timeout )
523 else:
Devin Limdc78e202017-06-09 18:30:07 -0700524 i = self.handle.expect( ["onos>", self.prompt], timeout )
Jon Hall63604932015-02-26 17:09:50 -0800525 response = self.handle.before
Jon Hall63604932015-02-26 17:09:50 -0800526 # TODO: do something with i
Jon Hallc6793552016-01-19 14:18:37 -0800527 main.log.info( "Command '" + str( cmdStr ) + "' sent to "
528 + self.name + "." )
Jon Hallc6358dd2015-04-10 12:44:28 -0700529 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700530 main.log.debug( self.name + ": Raw output" )
531 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700532
533 # Remove ANSI color control strings from output
kelvin-onlabd3b64892015-01-20 13:26:24 -0800534 ansiEscape = re.compile( r'\x1b[^m]*m' )
Jon Hall63604932015-02-26 17:09:50 -0800535 response = ansiEscape.sub( '', response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700536 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700537 main.log.debug( self.name + ": ansiEscape output" )
538 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700539
kelvin-onlabfb521662015-02-27 09:52:40 -0800540 # Remove extra return chars that get added
Jon Hall63604932015-02-26 17:09:50 -0800541 response = re.sub( r"\s\r", "", response )
Jon Hallc6358dd2015-04-10 12:44:28 -0700542 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700543 main.log.debug( self.name + ": Removed extra returns " +
544 "from output" )
545 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700546
547 # Strip excess whitespace
Jon Hall63604932015-02-26 17:09:50 -0800548 response = response.strip()
Jon Hallc6358dd2015-04-10 12:44:28 -0700549 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700550 main.log.debug( self.name + ": parsed and stripped output" )
551 main.log.debug( self.name + ": " + repr( response ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700552
Jon Hall63604932015-02-26 17:09:50 -0800553 # parse for just the output, remove the cmd from response
Jon Hallc6358dd2015-04-10 12:44:28 -0700554 output = response.split( cmdStr.strip(), 1 )
555 if debug:
Jon Hall390696c2015-05-05 17:13:41 -0700556 main.log.debug( self.name + ": split output" )
Jon Hallc6358dd2015-04-10 12:44:28 -0700557 for r in output:
Jon Hall390696c2015-05-05 17:13:41 -0700558 main.log.debug( self.name + ": " + repr( r ) )
GlennRC85870432015-11-23 11:45:51 -0800559 output = output[1].strip()
560 if showResponse:
GlennRCed771242016-01-13 17:02:47 -0800561 main.log.info( "Response from ONOS: {}".format( output ) )
GlennRC85870432015-11-23 11:45:51 -0800562 return output
GlennRCed771242016-01-13 17:02:47 -0800563 except pexpect.TIMEOUT:
564 main.log.error( self.name + ":ONOS timeout" )
565 if debug:
566 main.log.debug( self.handle.before )
567 return None
Jon Hallc6358dd2015-04-10 12:44:28 -0700568 except IndexError:
569 main.log.exception( self.name + ": Object not as expected" )
Jon Halla495f562016-05-16 18:03:26 -0700570 main.log.debug( "response: {}".format( repr( response ) ) )
Jon Hallc6358dd2015-04-10 12:44:28 -0700571 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800572 except TypeError:
573 main.log.exception( self.name + ": Object not as expected" )
574 return None
andrewonlaba18f6bf2014-10-13 19:31:54 -0400575 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800576 main.log.error( self.name + ": EOF exception found" )
577 main.log.error( self.name + ": " + self.handle.before )
YPZhangebf9eb52016-05-12 15:20:24 -0700578 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700579 return None
580 else:
581 main.cleanup()
582 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800583 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800584 main.log.exception( self.name + ": Uncaught exception!" )
YPZhangebf9eb52016-05-12 15:20:24 -0700585 if noExit:
YPZhangebf9eb52016-05-12 15:20:24 -0700586 return None
587 else:
588 main.cleanup()
589 main.exit()
andrewonlaba18f6bf2014-10-13 19:31:54 -0400590
kelvin8ec71442015-01-15 16:57:00 -0800591 # IMPORTANT NOTE:
592 # For all cli commands, naming convention should match
kelvin-onlabd3b64892015-01-20 13:26:24 -0800593 # the cli command changing 'a:b' with 'aB'.
594 # Ex ) onos:topology > onosTopology
595 # onos:links > onosLinks
596 # feature:list > featureList
Jon Halle3f39ff2015-01-13 11:50:53 -0800597
kelvin-onlabd3b64892015-01-20 13:26:24 -0800598 def addNode( self, nodeId, ONOSIp, tcpPort="" ):
kelvin8ec71442015-01-15 16:57:00 -0800599 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400600 Adds a new cluster node by ID and address information.
601 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800602 * nodeId
603 * ONOSIp
andrewonlabc2d05aa2014-10-13 16:51:10 -0400604 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800605 * tcpPort
kelvin8ec71442015-01-15 16:57:00 -0800606 """
andrewonlabc2d05aa2014-10-13 16:51:10 -0400607 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800608 cmdStr = "add-node " + str( nodeId ) + " " +\
609 str( ONOSIp ) + " " + str( tcpPort )
610 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700611 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800612 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -0800613 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -0800614 main.log.error( "Error in adding node" )
615 main.log.error( handle )
Jon Halle3f39ff2015-01-13 11:50:53 -0800616 return main.FALSE
andrewonlabc2d05aa2014-10-13 16:51:10 -0400617 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800618 main.log.info( "Node " + str( ONOSIp ) + " added" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400619 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800620 except AssertionError:
621 main.log.exception( "" )
622 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800623 except TypeError:
624 main.log.exception( self.name + ": Object not as expected" )
625 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400626 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800627 main.log.error( self.name + ": EOF exception found" )
628 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400629 main.cleanup()
630 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800631 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800632 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400633 main.cleanup()
634 main.exit()
635
kelvin-onlabd3b64892015-01-20 13:26:24 -0800636 def removeNode( self, nodeId ):
kelvin8ec71442015-01-15 16:57:00 -0800637 """
andrewonlab86dc3082014-10-13 18:18:38 -0400638 Removes a cluster by ID
639 Issues command: 'remove-node [<node-id>]'
640 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800641 * nodeId
kelvin8ec71442015-01-15 16:57:00 -0800642 """
andrewonlab86dc3082014-10-13 18:18:38 -0400643 try:
andrewonlab86dc3082014-10-13 18:18:38 -0400644
kelvin-onlabd3b64892015-01-20 13:26:24 -0800645 cmdStr = "remove-node " + str( nodeId )
Jon Hall08f61bc2015-04-13 16:00:30 -0700646 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700647 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800648 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700649 if re.search( "Error", handle ):
650 main.log.error( "Error in removing node" )
651 main.log.error( handle )
652 return main.FALSE
653 else:
654 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800655 except AssertionError:
656 main.log.exception( "" )
657 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800658 except TypeError:
659 main.log.exception( self.name + ": Object not as expected" )
660 return None
andrewonlab86dc3082014-10-13 18:18:38 -0400661 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800662 main.log.error( self.name + ": EOF exception found" )
663 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -0400664 main.cleanup()
665 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800666 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800667 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -0400668 main.cleanup()
669 main.exit()
andrewonlabc2d05aa2014-10-13 16:51:10 -0400670
Jon Hall61282e32015-03-19 11:34:11 -0700671 def nodes( self, jsonFormat=True):
kelvin8ec71442015-01-15 16:57:00 -0800672 """
andrewonlab7c211572014-10-15 16:45:20 -0400673 List the nodes currently visible
674 Issues command: 'nodes'
Jon Hall61282e32015-03-19 11:34:11 -0700675 Optional argument:
676 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800677 """
andrewonlab7c211572014-10-15 16:45:20 -0400678 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700679 cmdStr = "nodes"
Jon Hall61282e32015-03-19 11:34:11 -0700680 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700681 cmdStr += " -j"
682 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700683 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800684 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -0700685 return output
Jon Hallc6793552016-01-19 14:18:37 -0800686 except AssertionError:
687 main.log.exception( "" )
688 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800689 except TypeError:
690 main.log.exception( self.name + ": Object not as expected" )
691 return None
andrewonlab7c211572014-10-15 16:45:20 -0400692 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800693 main.log.error( self.name + ": EOF exception found" )
694 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400695 main.cleanup()
696 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800697 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800698 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400699 main.cleanup()
700 main.exit()
701
kelvin8ec71442015-01-15 16:57:00 -0800702 def topology( self ):
703 """
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700704 Definition:
Jon Hall390696c2015-05-05 17:13:41 -0700705 Returns the output of topology command.
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700706 Return:
707 topology = current ONOS topology
kelvin8ec71442015-01-15 16:57:00 -0800708 """
andrewonlab95ce8322014-10-13 14:12:04 -0400709 try:
Hari Krishnaef1bd4e2015-03-12 16:55:30 -0700710 cmdStr = "topology -j"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800711 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800712 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800713 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700714 main.log.info( cmdStr + " returned: " + str( handle ) )
andrewonlab95ce8322014-10-13 14:12:04 -0400715 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800716 except AssertionError:
717 main.log.exception( "" )
Jon Halld4d4b372015-01-28 16:02:41 -0800718 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800719 except TypeError:
720 main.log.exception( self.name + ": Object not as expected" )
721 return None
andrewonlabc2d05aa2014-10-13 16:51:10 -0400722 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800723 main.log.error( self.name + ": EOF exception found" )
724 main.log.error( self.name + ": " + self.handle.before )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400725 main.cleanup()
726 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800727 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800728 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabc2d05aa2014-10-13 16:51:10 -0400729 main.cleanup()
730 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -0800731
jenkins7ead5a82015-03-13 10:28:21 -0700732 def deviceRemove( self, deviceId ):
733 """
734 Removes particular device from storage
735
736 TODO: refactor this function
737 """
738 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700739 cmdStr = "device-remove " + str( deviceId )
740 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800741 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800742 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700743 if re.search( "Error", handle ):
744 main.log.error( "Error in removing device" )
745 main.log.error( handle )
746 return main.FALSE
747 else:
748 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800749 except AssertionError:
750 main.log.exception( "" )
751 return None
jenkins7ead5a82015-03-13 10:28:21 -0700752 except TypeError:
753 main.log.exception( self.name + ": Object not as expected" )
754 return None
755 except pexpect.EOF:
756 main.log.error( self.name + ": EOF exception found" )
757 main.log.error( self.name + ": " + self.handle.before )
758 main.cleanup()
759 main.exit()
760 except Exception:
761 main.log.exception( self.name + ": Uncaught exception!" )
762 main.cleanup()
763 main.exit()
jenkins7ead5a82015-03-13 10:28:21 -0700764
kelvin-onlabd3b64892015-01-20 13:26:24 -0800765 def devices( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800766 """
Jon Hall7b02d952014-10-17 20:14:54 -0400767 Lists all infrastructure devices or switches
andrewonlab86dc3082014-10-13 18:18:38 -0400768 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800769 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800770 """
andrewonlab86dc3082014-10-13 18:18:38 -0400771 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700772 cmdStr = "devices"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800773 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700774 cmdStr += " -j"
775 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800776 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800777 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700778 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800779 except AssertionError:
780 main.log.exception( "" )
781 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800782 except TypeError:
783 main.log.exception( self.name + ": Object not as expected" )
784 return None
andrewonlab7c211572014-10-15 16:45:20 -0400785 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800786 main.log.error( self.name + ": EOF exception found" )
787 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -0400788 main.cleanup()
789 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800790 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800791 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -0400792 main.cleanup()
793 main.exit()
794
kelvin-onlabd3b64892015-01-20 13:26:24 -0800795 def balanceMasters( self ):
kelvin8ec71442015-01-15 16:57:00 -0800796 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800797 This balances the devices across all controllers
798 by issuing command: 'onos> onos:balance-masters'
799 If required this could be extended to return devices balanced output.
kelvin8ec71442015-01-15 16:57:00 -0800800 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800801 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800802 cmdStr = "onos:balance-masters"
Jon Hallc6358dd2015-04-10 12:44:28 -0700803 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800804 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800805 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700806 if re.search( "Error", handle ):
807 main.log.error( "Error in balancing masters" )
808 main.log.error( handle )
809 return main.FALSE
810 else:
811 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800812 except AssertionError:
813 main.log.exception( "" )
814 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800815 except TypeError:
816 main.log.exception( self.name + ": Object not as expected" )
817 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800818 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800819 main.log.error( self.name + ": EOF exception found" )
820 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800821 main.cleanup()
822 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800823 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800824 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -0800825 main.cleanup()
826 main.exit()
827
Jon Hallc6793552016-01-19 14:18:37 -0800828 def checkMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700829 """
830 Returns the output of the masters command.
831 Optional argument:
832 * jsonFormat - boolean indicating if you want output in json
833 """
834 try:
835 cmdStr = "onos:masters"
836 if jsonFormat:
837 cmdStr += " -j"
838 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -0700839 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800840 assert "Command not found:" not in output, output
acsmars24950022015-07-30 18:00:43 -0700841 return output
Jon Hallc6793552016-01-19 14:18:37 -0800842 except AssertionError:
843 main.log.exception( "" )
844 return None
acsmars24950022015-07-30 18:00:43 -0700845 except TypeError:
846 main.log.exception( self.name + ": Object not as expected" )
847 return None
848 except pexpect.EOF:
849 main.log.error( self.name + ": EOF exception found" )
850 main.log.error( self.name + ": " + self.handle.before )
851 main.cleanup()
852 main.exit()
853 except Exception:
854 main.log.exception( self.name + ": Uncaught exception!" )
855 main.cleanup()
856 main.exit()
857
Jon Hallc6793552016-01-19 14:18:37 -0800858 def checkBalanceMasters( self, jsonFormat=True ):
acsmars24950022015-07-30 18:00:43 -0700859 """
860 Uses the master command to check that the devices' leadership
861 is evenly divided
862
863 Dependencies: checkMasters() and summary()
864
Jon Hall6509dbf2016-06-21 17:01:17 -0700865 Returns main.TRUE if the devices are balanced
866 Returns main.FALSE if the devices are unbalanced
acsmars24950022015-07-30 18:00:43 -0700867 Exits on Exception
868 Returns None on TypeError
869 """
870 try:
Jon Hallc6793552016-01-19 14:18:37 -0800871 summaryOutput = self.summary()
872 totalDevices = json.loads( summaryOutput )[ "devices" ]
873 except ( TypeError, ValueError ):
874 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summaryOutput ) )
875 return None
876 try:
acsmars24950022015-07-30 18:00:43 -0700877 totalOwnedDevices = 0
Jon Hallc6793552016-01-19 14:18:37 -0800878 mastersOutput = self.checkMasters()
879 masters = json.loads( mastersOutput )
acsmars24950022015-07-30 18:00:43 -0700880 first = masters[ 0 ][ "size" ]
881 for master in masters:
882 totalOwnedDevices += master[ "size" ]
883 if master[ "size" ] > first + 1 or master[ "size" ] < first - 1:
884 main.log.error( "Mastership not balanced" )
885 main.log.info( "\n" + self.checkMasters( False ) )
886 return main.FALSE
Jon Halle0f0b342017-04-18 11:43:47 -0700887 main.log.info( "Mastership balanced between " +
888 str( len(masters) ) + " masters" )
acsmars24950022015-07-30 18:00:43 -0700889 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -0800890 except ( TypeError, ValueError ):
891 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, mastersOutput ) )
acsmars24950022015-07-30 18:00:43 -0700892 return None
893 except pexpect.EOF:
894 main.log.error( self.name + ": EOF exception found" )
895 main.log.error( self.name + ": " + self.handle.before )
896 main.cleanup()
897 main.exit()
898 except Exception:
899 main.log.exception( self.name + ": Uncaught exception!" )
900 main.cleanup()
901 main.exit()
902
YPZhangfebf7302016-05-24 16:45:56 -0700903 def links( self, jsonFormat=True, timeout=30 ):
kelvin8ec71442015-01-15 16:57:00 -0800904 """
Jon Halle8217482014-10-17 13:49:14 -0400905 Lists all core links
906 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800907 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800908 """
Jon Halle8217482014-10-17 13:49:14 -0400909 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700910 cmdStr = "links"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800911 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700912 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -0700913 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -0800914 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800915 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700916 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800917 except AssertionError:
918 main.log.exception( "" )
919 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800920 except TypeError:
921 main.log.exception( self.name + ": Object not as expected" )
922 return None
Jon Halle8217482014-10-17 13:49:14 -0400923 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800924 main.log.error( self.name + ": EOF exception found" )
925 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400926 main.cleanup()
927 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800928 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800929 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400930 main.cleanup()
931 main.exit()
932
kelvin-onlabd3b64892015-01-20 13:26:24 -0800933 def ports( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800934 """
Jon Halle8217482014-10-17 13:49:14 -0400935 Lists all ports
936 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800937 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800938 """
Jon Halle8217482014-10-17 13:49:14 -0400939 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700940 cmdStr = "ports"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800941 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700942 cmdStr += " -j"
943 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800944 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800945 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700946 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800947 except AssertionError:
948 main.log.exception( "" )
949 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800950 except TypeError:
951 main.log.exception( self.name + ": Object not as expected" )
952 return None
Jon Halle8217482014-10-17 13:49:14 -0400953 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800954 main.log.error( self.name + ": EOF exception found" )
955 main.log.error( self.name + ": " + self.handle.before )
Jon Halle8217482014-10-17 13:49:14 -0400956 main.cleanup()
957 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800958 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800959 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle8217482014-10-17 13:49:14 -0400960 main.cleanup()
961 main.exit()
962
kelvin-onlabd3b64892015-01-20 13:26:24 -0800963 def roles( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -0800964 """
Jon Hall983a1702014-10-28 18:44:22 -0400965 Lists all devices and the controllers with roles assigned to them
966 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -0800967 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -0800968 """
andrewonlab7c211572014-10-15 16:45:20 -0400969 try:
Jon Hallc6358dd2015-04-10 12:44:28 -0700970 cmdStr = "roles"
kelvin-onlabd3b64892015-01-20 13:26:24 -0800971 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -0700972 cmdStr += " -j"
973 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -0800974 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -0800975 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -0700976 return handle
Jon Hallc6793552016-01-19 14:18:37 -0800977 except AssertionError:
978 main.log.exception( "" )
979 return None
Jon Halld4d4b372015-01-28 16:02:41 -0800980 except TypeError:
981 main.log.exception( self.name + ": Object not as expected" )
982 return None
Jon Hall983a1702014-10-28 18:44:22 -0400983 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -0800984 main.log.error( self.name + ": EOF exception found" )
985 main.log.error( self.name + ": " + self.handle.before )
Jon Hall983a1702014-10-28 18:44:22 -0400986 main.cleanup()
987 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -0800988 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -0800989 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall983a1702014-10-28 18:44:22 -0400990 main.cleanup()
991 main.exit()
992
kelvin-onlabd3b64892015-01-20 13:26:24 -0800993 def getRole( self, deviceId ):
kelvin-onlab898a6c62015-01-16 14:13:53 -0800994 """
Jon Halle3f39ff2015-01-13 11:50:53 -0800995 Given the a string containing the json representation of the "roles"
996 cli command and a partial or whole device id, returns a json object
997 containing the roles output for the first device whose id contains
998 "device_id"
Jon Hall983a1702014-10-28 18:44:22 -0400999
1000 Returns:
Jon Halle3f39ff2015-01-13 11:50:53 -08001001 A dict of the role assignments for the given device or
1002 None if no match
kelvin8ec71442015-01-15 16:57:00 -08001003 """
Jon Hall983a1702014-10-28 18:44:22 -04001004 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001005 if deviceId is None:
Jon Hall983a1702014-10-28 18:44:22 -04001006 return None
1007 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001008 rawRoles = self.roles()
1009 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001010 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001011 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001012 # print device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001013 if str( deviceId ) in device[ 'id' ]:
Jon Hall983a1702014-10-28 18:44:22 -04001014 return device
1015 return None
Jon Hallc6793552016-01-19 14:18:37 -08001016 except ( TypeError, ValueError ):
1017 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001018 return None
andrewonlab86dc3082014-10-13 18:18:38 -04001019 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001020 main.log.error( self.name + ": EOF exception found" )
1021 main.log.error( self.name + ": " + self.handle.before )
andrewonlab86dc3082014-10-13 18:18:38 -04001022 main.cleanup()
1023 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001024 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001025 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab86dc3082014-10-13 18:18:38 -04001026 main.cleanup()
1027 main.exit()
Jon Hall94fd0472014-12-08 11:52:42 -08001028
kelvin-onlabd3b64892015-01-20 13:26:24 -08001029 def rolesNotNull( self ):
kelvin8ec71442015-01-15 16:57:00 -08001030 """
Jon Hall94fd0472014-12-08 11:52:42 -08001031 Iterates through each device and checks if there is a master assigned
1032 Returns: main.TRUE if each device has a master
1033 main.FALSE any device has no master
kelvin8ec71442015-01-15 16:57:00 -08001034 """
Jon Hall94fd0472014-12-08 11:52:42 -08001035 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001036 rawRoles = self.roles()
1037 rolesJson = json.loads( rawRoles )
kelvin8ec71442015-01-15 16:57:00 -08001038 # search json for the device with id then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001039 for device in rolesJson:
kelvin8ec71442015-01-15 16:57:00 -08001040 # print device
1041 if device[ 'master' ] == "none":
1042 main.log.warn( "Device has no master: " + str( device ) )
Jon Hall94fd0472014-12-08 11:52:42 -08001043 return main.FALSE
1044 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08001045 except ( TypeError, ValueError ):
1046 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawRoles ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001047 return None
Jon Hall94fd0472014-12-08 11:52:42 -08001048 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001049 main.log.error( self.name + ": EOF exception found" )
1050 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08001051 main.cleanup()
1052 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001053 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001054 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08001055 main.cleanup()
1056 main.exit()
1057
kelvin-onlabd3b64892015-01-20 13:26:24 -08001058 def paths( self, srcId, dstId ):
kelvin8ec71442015-01-15 16:57:00 -08001059 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001060 Returns string of paths, and the cost.
1061 Issues command: onos:paths <src> <dst>
kelvin8ec71442015-01-15 16:57:00 -08001062 """
andrewonlab3e15ead2014-10-15 14:21:34 -04001063 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001064 cmdStr = "onos:paths " + str( srcId ) + " " + str( dstId )
1065 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001066 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001067 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001068 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001069 main.log.error( "Error in getting paths" )
1070 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001071 else:
kelvin8ec71442015-01-15 16:57:00 -08001072 path = handle.split( ";" )[ 0 ]
1073 cost = handle.split( ";" )[ 1 ]
1074 return ( path, cost )
Jon Hallc6793552016-01-19 14:18:37 -08001075 except AssertionError:
1076 main.log.exception( "" )
1077 return ( handle, "Error" )
Jon Halld4d4b372015-01-28 16:02:41 -08001078 except TypeError:
1079 main.log.exception( self.name + ": Object not as expected" )
1080 return ( handle, "Error" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001081 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001082 main.log.error( self.name + ": EOF exception found" )
1083 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3e15ead2014-10-15 14:21:34 -04001084 main.cleanup()
1085 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001086 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001087 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3e15ead2014-10-15 14:21:34 -04001088 main.cleanup()
1089 main.exit()
Jon Hallffb386d2014-11-21 13:43:38 -08001090
kelvin-onlabd3b64892015-01-20 13:26:24 -08001091 def hosts( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08001092 """
Jon Hallffb386d2014-11-21 13:43:38 -08001093 Lists all discovered hosts
Jon Hall42db6dc2014-10-24 19:03:48 -04001094 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001095 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08001096 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001097 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001098 cmdStr = "hosts"
kelvin-onlabd3b64892015-01-20 13:26:24 -08001099 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07001100 cmdStr += " -j"
1101 handle = self.sendline( cmdStr )
Jeremyd9e4eb12016-04-13 12:09:06 -07001102 if handle:
1103 assert "Command not found:" not in handle, handle
Jon Hallbaf53162015-12-17 17:04:34 -08001104 # TODO: Maybe make this less hardcoded
1105 # ConsistentMap Exceptions
1106 assert "org.onosproject.store.service" not in handle
1107 # Node not leader
1108 assert "java.lang.IllegalStateException" not in handle
Jon Hallc6358dd2015-04-10 12:44:28 -07001109 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001110 except AssertionError:
Jeremyd9e4eb12016-04-13 12:09:06 -07001111 main.log.exception( "Error in processing '" + cmdStr + "' " +
Jeremy Songster6949cea2016-04-19 18:13:18 -07001112 "command: " + str( handle ) )
Jon Hallc6793552016-01-19 14:18:37 -08001113 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001114 except TypeError:
1115 main.log.exception( self.name + ": Object not as expected" )
1116 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001117 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001118 main.log.error( self.name + ": EOF exception found" )
1119 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001120 main.cleanup()
1121 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001122 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001123 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001124 main.cleanup()
1125 main.exit()
1126
kelvin-onlabd3b64892015-01-20 13:26:24 -08001127 def getHost( self, mac ):
kelvin8ec71442015-01-15 16:57:00 -08001128 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001129 Return the first host from the hosts api whose 'id' contains 'mac'
Jon Halle3f39ff2015-01-13 11:50:53 -08001130
Jon Hallefbd9792015-03-05 16:11:36 -08001131 Note: mac must be a colon separated mac address, but could be a
Jon Halle3f39ff2015-01-13 11:50:53 -08001132 partial mac address
1133
Jon Hall42db6dc2014-10-24 19:03:48 -04001134 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08001135 """
Jon Hall42db6dc2014-10-24 19:03:48 -04001136 try:
kelvin8ec71442015-01-15 16:57:00 -08001137 if mac is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04001138 return None
1139 else:
1140 mac = mac
kelvin-onlabd3b64892015-01-20 13:26:24 -08001141 rawHosts = self.hosts()
1142 hostsJson = json.loads( rawHosts )
kelvin8ec71442015-01-15 16:57:00 -08001143 # search json for the host with mac then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08001144 for host in hostsJson:
kelvin8ec71442015-01-15 16:57:00 -08001145 # print "%s in %s?" % ( mac, host[ 'id' ] )
Jon Halld4d4b372015-01-28 16:02:41 -08001146 if not host:
1147 pass
1148 elif mac in host[ 'id' ]:
Jon Hall42db6dc2014-10-24 19:03:48 -04001149 return host
1150 return None
Jon Hallc6793552016-01-19 14:18:37 -08001151 except ( TypeError, ValueError ):
1152 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawHosts ) )
Jon Halld4d4b372015-01-28 16:02:41 -08001153 return None
Jon Hall42db6dc2014-10-24 19:03:48 -04001154 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001155 main.log.error( self.name + ": EOF exception found" )
1156 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04001157 main.cleanup()
1158 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001159 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001160 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04001161 main.cleanup()
1162 main.exit()
1163
kelvin-onlabd3b64892015-01-20 13:26:24 -08001164 def getHostsId( self, hostList ):
kelvin8ec71442015-01-15 16:57:00 -08001165 """
1166 Obtain list of hosts
andrewonlab3f0a4af2014-10-17 12:25:14 -04001167 Issues command: 'onos> hosts'
kelvin8ec71442015-01-15 16:57:00 -08001168
andrewonlab3f0a4af2014-10-17 12:25:14 -04001169 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001170 * hostList: List of hosts obtained by Mininet
andrewonlab3f0a4af2014-10-17 12:25:14 -04001171 IMPORTANT:
1172 This function assumes that you started your
kelvin8ec71442015-01-15 16:57:00 -08001173 topology with the option '--mac'.
andrewonlab3f0a4af2014-10-17 12:25:14 -04001174 Furthermore, it assumes that value of VLAN is '-1'
1175 Description:
kelvin8ec71442015-01-15 16:57:00 -08001176 Converts mininet hosts ( h1, h2, h3... ) into
1177 ONOS format ( 00:00:00:00:00:01/-1 , ... )
1178 """
andrewonlab3f0a4af2014-10-17 12:25:14 -04001179 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001180 onosHostList = []
andrewonlab3f0a4af2014-10-17 12:25:14 -04001181
kelvin-onlabd3b64892015-01-20 13:26:24 -08001182 for host in hostList:
kelvin8ec71442015-01-15 16:57:00 -08001183 host = host.replace( "h", "" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001184 hostHex = hex( int( host ) ).zfill( 12 )
1185 hostHex = str( hostHex ).replace( 'x', '0' )
1186 i = iter( str( hostHex ) )
1187 hostHex = ":".join( a + b for a, b in zip( i, i ) )
1188 hostHex = hostHex + "/-1"
1189 onosHostList.append( hostHex )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001190
kelvin-onlabd3b64892015-01-20 13:26:24 -08001191 return onosHostList
andrewonlab3f0a4af2014-10-17 12:25:14 -04001192
Jon Halld4d4b372015-01-28 16:02:41 -08001193 except TypeError:
1194 main.log.exception( self.name + ": Object not as expected" )
1195 return None
andrewonlab3f0a4af2014-10-17 12:25:14 -04001196 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001197 main.log.error( self.name + ": EOF exception found" )
1198 main.log.error( self.name + ": " + self.handle.before )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001199 main.cleanup()
1200 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001201 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001202 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab3f0a4af2014-10-17 12:25:14 -04001203 main.cleanup()
1204 main.exit()
andrewonlab3e15ead2014-10-15 14:21:34 -04001205
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001206 def addHostIntent( self, hostIdOne, hostIdTwo, vlanId="", setVlan="", encap="", bandwidth="" ):
kelvin8ec71442015-01-15 16:57:00 -08001207 """
andrewonlabe6745342014-10-17 14:29:13 -04001208 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001209 * hostIdOne: ONOS host id for host1
1210 * hostIdTwo: ONOS host id for host2
Jeremy Songster832f9e92016-05-05 14:30:49 -07001211 Optional:
1212 * vlanId: specify a VLAN id for the intent
Jeremy Songsterff553672016-05-12 17:06:23 -07001213 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001214 * encap: specify an encapsulation type
andrewonlabe6745342014-10-17 14:29:13 -04001215 Description:
Jon Hallefbd9792015-03-05 16:11:36 -08001216 Adds a host-to-host intent ( bidirectional ) by
Jon Hallb1290e82014-11-18 16:17:48 -05001217 specifying the two hosts.
kelvin-onlabfb521662015-02-27 09:52:40 -08001218 Returns:
1219 A string of the intent id or None on Error
kelvin8ec71442015-01-15 16:57:00 -08001220 """
andrewonlabe6745342014-10-17 14:29:13 -04001221 try:
Jeremy Songster832f9e92016-05-05 14:30:49 -07001222 cmdStr = "add-host-intent "
1223 if vlanId:
1224 cmdStr += "-v " + str( vlanId ) + " "
Jeremy Songsterff553672016-05-12 17:06:23 -07001225 if setVlan:
1226 cmdStr += "--setVlan " + str( vlanId ) + " "
Jeremy Songsterc032f162016-08-04 17:14:49 -07001227 if encap:
1228 cmdStr += "--encapsulation " + str( encap ) + " "
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07001229 if bandwidth:
1230 cmdStr += "-b " + str( bandwidth ) + " "
Jeremy Songster832f9e92016-05-05 14:30:49 -07001231 cmdStr += str( hostIdOne ) + " " + str( hostIdTwo )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001232 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001233 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001234 assert "Command not found:" not in handle, handle
Hari Krishnaac4e1782015-01-26 12:09:12 -08001235 if re.search( "Error", handle ):
1236 main.log.error( "Error in adding Host intent" )
Jon Hall61282e32015-03-19 11:34:11 -07001237 main.log.debug( "Response from ONOS was: " + repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001238 return None
Hari Krishnaac4e1782015-01-26 12:09:12 -08001239 else:
1240 main.log.info( "Host intent installed between " +
kelvin-onlabfb521662015-02-27 09:52:40 -08001241 str( hostIdOne ) + " and " + str( hostIdTwo ) )
1242 match = re.search('id=0x([\da-f]+),', handle)
1243 if match:
1244 return match.group()[3:-1]
1245 else:
1246 main.log.error( "Error, intent ID not found" )
Jon Hall61282e32015-03-19 11:34:11 -07001247 main.log.debug( "Response from ONOS was: " +
1248 repr( handle ) )
kelvin-onlabfb521662015-02-27 09:52:40 -08001249 return None
Jon Hallc6793552016-01-19 14:18:37 -08001250 except AssertionError:
1251 main.log.exception( "" )
1252 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001253 except TypeError:
1254 main.log.exception( self.name + ": Object not as expected" )
1255 return None
andrewonlabe6745342014-10-17 14:29:13 -04001256 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001257 main.log.error( self.name + ": EOF exception found" )
1258 main.log.error( self.name + ": " + self.handle.before )
andrewonlabe6745342014-10-17 14:29:13 -04001259 main.cleanup()
1260 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001261 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001262 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04001263 main.cleanup()
1264 main.exit()
1265
kelvin-onlabd3b64892015-01-20 13:26:24 -08001266 def addOpticalIntent( self, ingressDevice, egressDevice ):
kelvin8ec71442015-01-15 16:57:00 -08001267 """
andrewonlab7b31d232014-10-24 13:31:47 -04001268 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001269 * ingressDevice: device id of ingress device
1270 * egressDevice: device id of egress device
andrewonlab7b31d232014-10-24 13:31:47 -04001271 Optional:
1272 TODO: Still needs to be implemented via dev side
kelvin-onlabfb521662015-02-27 09:52:40 -08001273 Description:
1274 Adds an optical intent by specifying an ingress and egress device
1275 Returns:
1276 A string of the intent id or None on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08001277 """
andrewonlab7b31d232014-10-24 13:31:47 -04001278 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001279 cmdStr = "add-optical-intent " + str( ingressDevice ) +\
1280 " " + str( egressDevice )
1281 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001282 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001283 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08001284 # If error, return error message
Jon Halle3f39ff2015-01-13 11:50:53 -08001285 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001286 main.log.error( "Error in adding Optical intent" )
1287 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001288 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001289 main.log.info( "Optical intent installed between " +
1290 str( ingressDevice ) + " and " +
1291 str( egressDevice ) )
1292 match = re.search('id=0x([\da-f]+),', handle)
1293 if match:
1294 return match.group()[3:-1]
1295 else:
1296 main.log.error( "Error, intent ID not found" )
1297 return None
Jon Hallc6793552016-01-19 14:18:37 -08001298 except AssertionError:
1299 main.log.exception( "" )
1300 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001301 except TypeError:
1302 main.log.exception( self.name + ": Object not as expected" )
1303 return None
andrewonlab7b31d232014-10-24 13:31:47 -04001304 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001305 main.log.error( self.name + ": EOF exception found" )
1306 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7b31d232014-10-24 13:31:47 -04001307 main.cleanup()
1308 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001309 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001310 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7b31d232014-10-24 13:31:47 -04001311 main.cleanup()
1312 main.exit()
1313
kelvin-onlabd3b64892015-01-20 13:26:24 -08001314 def addPointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001315 self,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001316 ingressDevice,
1317 egressDevice,
1318 portIngress="",
1319 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001320 ethType="",
1321 ethSrc="",
1322 ethDst="",
1323 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001324 lambdaAlloc=False,
alisonda157272016-12-22 01:13:21 -08001325 protected=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001326 ipProto="",
1327 ipSrc="",
1328 ipDst="",
1329 tcpSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001330 tcpDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001331 vlanId="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001332 setVlan="",
1333 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001334 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001335 Required:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001336 * ingressDevice: device id of ingress device
1337 * egressDevice: device id of egress device
andrewonlab289e4b72014-10-21 21:24:18 -04001338 Optional:
1339 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001340 * ethSrc: specify ethSrc ( i.e. src mac addr )
1341 * ethDst: specify ethDst ( i.e. dst mac addr )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05001342 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001343 * lambdaAlloc: if True, intent will allocate lambda
andrewonlab40ccd8b2014-11-06 16:23:34 -05001344 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001345 * ipProto: specify ip protocol
andrewonlabf77e0cb2014-11-11 17:17:59 -05001346 * ipSrc: specify ip source address
1347 * ipDst: specify ip destination address
1348 * tcpSrc: specify tcp source port
1349 * tcpDst: specify tcp destination port
Jeremy Songster832f9e92016-05-05 14:30:49 -07001350 * vlanId: specify vlan ID
Jeremy Songsterff553672016-05-12 17:06:23 -07001351 * setVlan: specify a VLAN id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001352 * encap: specify an Encapsulation type to use
andrewonlab4dbb4d82014-10-17 18:22:31 -04001353 Description:
kelvin8ec71442015-01-15 16:57:00 -08001354 Adds a point-to-point intent ( uni-directional ) by
andrewonlab289e4b72014-10-21 21:24:18 -04001355 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001356 Returns:
1357 A string of the intent id or None on error
andrewonlab289e4b72014-10-21 21:24:18 -04001358
Jon Halle3f39ff2015-01-13 11:50:53 -08001359 NOTE: This function may change depending on the
andrewonlab4dbb4d82014-10-17 18:22:31 -04001360 options developers provide for point-to-point
1361 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001362 """
andrewonlab4dbb4d82014-10-17 18:22:31 -04001363 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001364 cmd = "add-point-intent"
andrewonlab36af3822014-11-18 17:48:18 -05001365
Jeremy Songsterff553672016-05-12 17:06:23 -07001366 if ethType:
1367 cmd += " --ethType " + str( ethType )
1368 if ethSrc:
1369 cmd += " --ethSrc " + str( ethSrc )
1370 if ethDst:
1371 cmd += " --ethDst " + str( ethDst )
1372 if bandwidth:
1373 cmd += " --bandwidth " + str( bandwidth )
1374 if lambdaAlloc:
1375 cmd += " --lambda "
1376 if ipProto:
1377 cmd += " --ipProto " + str( ipProto )
1378 if ipSrc:
1379 cmd += " --ipSrc " + str( ipSrc )
1380 if ipDst:
1381 cmd += " --ipDst " + str( ipDst )
1382 if tcpSrc:
1383 cmd += " --tcpSrc " + str( tcpSrc )
1384 if tcpDst:
1385 cmd += " --tcpDst " + str( tcpDst )
1386 if vlanId:
1387 cmd += " -v " + str( vlanId )
1388 if setVlan:
1389 cmd += " --setVlan " + str( setVlan )
Jeremy Songsterc032f162016-08-04 17:14:49 -07001390 if encap:
1391 cmd += " --encapsulation " + str( encap )
alisonda157272016-12-22 01:13:21 -08001392 if protected:
1393 cmd += " --protect "
andrewonlab289e4b72014-10-21 21:24:18 -04001394
kelvin8ec71442015-01-15 16:57:00 -08001395 # Check whether the user appended the port
1396 # or provided it as an input
kelvin-onlabd3b64892015-01-20 13:26:24 -08001397 if "/" in ingressDevice:
1398 cmd += " " + str( ingressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001399 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001400 if not portIngress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001401 main.log.error( "You must specify the ingress port" )
kelvin8ec71442015-01-15 16:57:00 -08001402 # TODO: perhaps more meaningful return
kelvin-onlabfb521662015-02-27 09:52:40 -08001403 # Would it make sense to throw an exception and exit
1404 # the test?
1405 return None
andrewonlab36af3822014-11-18 17:48:18 -05001406
kelvin8ec71442015-01-15 16:57:00 -08001407 cmd += " " + \
kelvin-onlabd3b64892015-01-20 13:26:24 -08001408 str( ingressDevice ) + "/" +\
1409 str( portIngress ) + " "
andrewonlab36af3822014-11-18 17:48:18 -05001410
kelvin-onlabd3b64892015-01-20 13:26:24 -08001411 if "/" in egressDevice:
1412 cmd += " " + str( egressDevice )
andrewonlab36af3822014-11-18 17:48:18 -05001413 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001414 if not portEgress:
kelvin-onlabfb521662015-02-27 09:52:40 -08001415 main.log.error( "You must specify the egress port" )
1416 return None
Jon Halle3f39ff2015-01-13 11:50:53 -08001417
kelvin8ec71442015-01-15 16:57:00 -08001418 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001419 str( egressDevice ) + "/" +\
1420 str( portEgress )
kelvin8ec71442015-01-15 16:57:00 -08001421
kelvin-onlab898a6c62015-01-16 14:13:53 -08001422 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001423 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001424 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001425 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001426 if re.search( "Error", handle ):
kelvin8ec71442015-01-15 16:57:00 -08001427 main.log.error( "Error in adding point-to-point intent" )
kelvin-onlabfb521662015-02-27 09:52:40 -08001428 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001429 else:
kelvin-onlabfb521662015-02-27 09:52:40 -08001430 # TODO: print out all the options in this message?
1431 main.log.info( "Point-to-point intent installed between " +
1432 str( ingressDevice ) + " and " +
1433 str( egressDevice ) )
1434 match = re.search('id=0x([\da-f]+),', handle)
1435 if match:
1436 return match.group()[3:-1]
1437 else:
1438 main.log.error( "Error, intent ID not found" )
1439 return None
Jon Hallc6793552016-01-19 14:18:37 -08001440 except AssertionError:
1441 main.log.exception( "" )
1442 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001443 except TypeError:
1444 main.log.exception( self.name + ": Object not as expected" )
1445 return None
andrewonlab4dbb4d82014-10-17 18:22:31 -04001446 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001447 main.log.error( self.name + ": EOF exception found" )
1448 main.log.error( self.name + ": " + self.handle.before )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001449 main.cleanup()
1450 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001451 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001452 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab4dbb4d82014-10-17 18:22:31 -04001453 main.cleanup()
1454 main.exit()
1455
kelvin-onlabd3b64892015-01-20 13:26:24 -08001456 def addMultipointToSinglepointIntent(
kelvin-onlab898a6c62015-01-16 14:13:53 -08001457 self,
shahshreyac2f97072015-03-19 17:04:29 -07001458 ingressDeviceList,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001459 egressDevice,
shahshreyac2f97072015-03-19 17:04:29 -07001460 portIngressList=None,
kelvin-onlabd3b64892015-01-20 13:26:24 -08001461 portEgress="",
kelvin-onlab898a6c62015-01-16 14:13:53 -08001462 ethType="",
1463 ethSrc="",
1464 ethDst="",
1465 bandwidth="",
kelvin-onlabd3b64892015-01-20 13:26:24 -08001466 lambdaAlloc=False,
kelvin-onlab898a6c62015-01-16 14:13:53 -08001467 ipProto="",
1468 ipSrc="",
1469 ipDst="",
1470 tcpSrc="",
1471 tcpDst="",
1472 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001473 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001474 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001475 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001476 partial=False,
1477 encap="" ):
kelvin8ec71442015-01-15 16:57:00 -08001478 """
shahshreyad0c80432014-12-04 16:56:05 -08001479 Note:
shahshreya70622b12015-03-19 17:19:00 -07001480 This function assumes the format of all ingress devices
Jon Hallbe379602015-03-24 13:39:32 -07001481 is same. That is, all ingress devices include port numbers
1482 with a "/" or all ingress devices could specify device
1483 ids and port numbers seperately.
shahshreyad0c80432014-12-04 16:56:05 -08001484 Required:
Jon Hallbe379602015-03-24 13:39:32 -07001485 * ingressDeviceList: List of device ids of ingress device
shahshreyac2f97072015-03-19 17:04:29 -07001486 ( Atleast 2 ingress devices required in the list )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001487 * egressDevice: device id of egress device
shahshreyad0c80432014-12-04 16:56:05 -08001488 Optional:
1489 * ethType: specify ethType
kelvin8ec71442015-01-15 16:57:00 -08001490 * ethSrc: specify ethSrc ( i.e. src mac addr )
1491 * ethDst: specify ethDst ( i.e. dst mac addr )
shahshreyad0c80432014-12-04 16:56:05 -08001492 * bandwidth: specify bandwidth capacity of link
kelvin-onlabd3b64892015-01-20 13:26:24 -08001493 * lambdaAlloc: if True, intent will allocate lambda
shahshreyad0c80432014-12-04 16:56:05 -08001494 for the specified intent
Jon Halle3f39ff2015-01-13 11:50:53 -08001495 * ipProto: specify ip protocol
shahshreyad0c80432014-12-04 16:56:05 -08001496 * ipSrc: specify ip source address
1497 * ipDst: specify ip destination address
1498 * tcpSrc: specify tcp source port
1499 * tcpDst: specify tcp destination port
1500 * setEthSrc: action to Rewrite Source MAC Address
1501 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001502 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001503 * setVlan: specify VLAN Id treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001504 * encap: specify a type of encapsulation
shahshreyad0c80432014-12-04 16:56:05 -08001505 Description:
kelvin8ec71442015-01-15 16:57:00 -08001506 Adds a multipoint-to-singlepoint intent ( uni-directional ) by
shahshreyad0c80432014-12-04 16:56:05 -08001507 specifying device id's and optional fields
kelvin-onlabfb521662015-02-27 09:52:40 -08001508 Returns:
1509 A string of the intent id or None on error
shahshreyad0c80432014-12-04 16:56:05 -08001510
Jon Halle3f39ff2015-01-13 11:50:53 -08001511 NOTE: This function may change depending on the
Jon Hallefbd9792015-03-05 16:11:36 -08001512 options developers provide for multipoint-to-singlepoint
shahshreyad0c80432014-12-04 16:56:05 -08001513 intent via cli
kelvin8ec71442015-01-15 16:57:00 -08001514 """
shahshreyad0c80432014-12-04 16:56:05 -08001515 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001516 cmd = "add-multi-to-single-intent"
shahshreyad0c80432014-12-04 16:56:05 -08001517
Jeremy Songsterff553672016-05-12 17:06:23 -07001518 if ethType:
1519 cmd += " --ethType " + str( ethType )
1520 if ethSrc:
1521 cmd += " --ethSrc " + str( ethSrc )
1522 if ethDst:
1523 cmd += " --ethDst " + str( ethDst )
1524 if bandwidth:
1525 cmd += " --bandwidth " + str( bandwidth )
1526 if lambdaAlloc:
1527 cmd += " --lambda "
1528 if ipProto:
1529 cmd += " --ipProto " + str( ipProto )
1530 if ipSrc:
1531 cmd += " --ipSrc " + str( ipSrc )
1532 if ipDst:
1533 cmd += " --ipDst " + str( ipDst )
1534 if tcpSrc:
1535 cmd += " --tcpSrc " + str( tcpSrc )
1536 if tcpDst:
1537 cmd += " --tcpDst " + str( tcpDst )
1538 if setEthSrc:
1539 cmd += " --setEthSrc " + str( setEthSrc )
1540 if setEthDst:
1541 cmd += " --setEthDst " + str( setEthDst )
1542 if vlanId:
1543 cmd += " -v " + str( vlanId )
1544 if setVlan:
1545 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001546 if partial:
1547 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001548 if encap:
1549 cmd += " --encapsulation " + str( encap )
shahshreyad0c80432014-12-04 16:56:05 -08001550
kelvin8ec71442015-01-15 16:57:00 -08001551 # Check whether the user appended the port
1552 # or provided it as an input
shahshreyac2f97072015-03-19 17:04:29 -07001553
1554 if portIngressList is None:
1555 for ingressDevice in ingressDeviceList:
1556 if "/" in ingressDevice:
1557 cmd += " " + str( ingressDevice )
1558 else:
1559 main.log.error( "You must specify " +
Jon Hallbe379602015-03-24 13:39:32 -07001560 "the ingress port" )
shahshreyac2f97072015-03-19 17:04:29 -07001561 # TODO: perhaps more meaningful return
1562 return main.FALSE
shahshreyad0c80432014-12-04 16:56:05 -08001563 else:
Jon Hall71ce4e72015-03-23 14:05:58 -07001564 if len( ingressDeviceList ) == len( portIngressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001565 for ingressDevice, portIngress in zip( ingressDeviceList,
1566 portIngressList ):
shahshreya70622b12015-03-19 17:19:00 -07001567 cmd += " " + \
1568 str( ingressDevice ) + "/" +\
1569 str( portIngress ) + " "
kelvin-onlab38143812015-04-01 15:03:01 -07001570 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001571 main.log.error( "Device list and port list does not " +
1572 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001573 return main.FALSE
kelvin-onlabd3b64892015-01-20 13:26:24 -08001574 if "/" in egressDevice:
1575 cmd += " " + str( egressDevice )
shahshreyad0c80432014-12-04 16:56:05 -08001576 else:
kelvin-onlabd3b64892015-01-20 13:26:24 -08001577 if not portEgress:
kelvin8ec71442015-01-15 16:57:00 -08001578 main.log.error( "You must specify " +
1579 "the egress port" )
shahshreyad0c80432014-12-04 16:56:05 -08001580 return main.FALSE
Jon Halle3f39ff2015-01-13 11:50:53 -08001581
kelvin8ec71442015-01-15 16:57:00 -08001582 cmd += " " +\
kelvin-onlabd3b64892015-01-20 13:26:24 -08001583 str( egressDevice ) + "/" +\
1584 str( portEgress )
kelvin-onlab898a6c62015-01-16 14:13:53 -08001585 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001586 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001587 assert "Command not found:" not in handle, handle
kelvin-onlabfb521662015-02-27 09:52:40 -08001588 # If error, return error message
kelvin-onlab898a6c62015-01-16 14:13:53 -08001589 if re.search( "Error", handle ):
kelvin-onlabfb521662015-02-27 09:52:40 -08001590 main.log.error( "Error in adding multipoint-to-singlepoint " +
1591 "intent" )
1592 return None
shahshreyad0c80432014-12-04 16:56:05 -08001593 else:
kelvin-onlabb9408212015-04-01 13:34:04 -07001594 match = re.search('id=0x([\da-f]+),', handle)
1595 if match:
1596 return match.group()[3:-1]
1597 else:
1598 main.log.error( "Error, intent ID not found" )
1599 return None
Jon Hallc6793552016-01-19 14:18:37 -08001600 except AssertionError:
1601 main.log.exception( "" )
1602 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001603 except TypeError:
1604 main.log.exception( self.name + ": Object not as expected" )
1605 return None
1606 except pexpect.EOF:
1607 main.log.error( self.name + ": EOF exception found" )
1608 main.log.error( self.name + ": " + self.handle.before )
1609 main.cleanup()
1610 main.exit()
1611 except Exception:
1612 main.log.exception( self.name + ": Uncaught exception!" )
1613 main.cleanup()
1614 main.exit()
1615
1616 def addSinglepointToMultipointIntent(
1617 self,
1618 ingressDevice,
1619 egressDeviceList,
1620 portIngress="",
1621 portEgressList=None,
1622 ethType="",
1623 ethSrc="",
1624 ethDst="",
1625 bandwidth="",
1626 lambdaAlloc=False,
1627 ipProto="",
1628 ipSrc="",
1629 ipDst="",
1630 tcpSrc="",
1631 tcpDst="",
1632 setEthSrc="",
Jeremy Songster832f9e92016-05-05 14:30:49 -07001633 setEthDst="",
Jeremy Songsterff553672016-05-12 17:06:23 -07001634 vlanId="",
Jeremy Songster9385d412016-06-02 17:57:36 -07001635 setVlan="",
Jeremy Songsterc032f162016-08-04 17:14:49 -07001636 partial=False,
1637 encap="" ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001638 """
1639 Note:
1640 This function assumes the format of all egress devices
1641 is same. That is, all egress devices include port numbers
1642 with a "/" or all egress devices could specify device
1643 ids and port numbers seperately.
1644 Required:
1645 * EgressDeviceList: List of device ids of egress device
1646 ( Atleast 2 eress devices required in the list )
1647 * ingressDevice: device id of ingress device
1648 Optional:
1649 * ethType: specify ethType
1650 * ethSrc: specify ethSrc ( i.e. src mac addr )
1651 * ethDst: specify ethDst ( i.e. dst mac addr )
1652 * bandwidth: specify bandwidth capacity of link
1653 * lambdaAlloc: if True, intent will allocate lambda
1654 for the specified intent
1655 * ipProto: specify ip protocol
1656 * ipSrc: specify ip source address
1657 * ipDst: specify ip destination address
1658 * tcpSrc: specify tcp source port
1659 * tcpDst: specify tcp destination port
1660 * setEthSrc: action to Rewrite Source MAC Address
1661 * setEthDst: action to Rewrite Destination MAC Address
Jeremy Songster832f9e92016-05-05 14:30:49 -07001662 * vlanId: specify vlan Id
Jeremy Songsterff553672016-05-12 17:06:23 -07001663 * setVlan: specify VLAN ID treatment
Jeremy Songsterc032f162016-08-04 17:14:49 -07001664 * encap: specify an encapsulation type
kelvin-onlabb9408212015-04-01 13:34:04 -07001665 Description:
1666 Adds a singlepoint-to-multipoint intent ( uni-directional ) by
1667 specifying device id's and optional fields
1668 Returns:
1669 A string of the intent id or None on error
1670
1671 NOTE: This function may change depending on the
1672 options developers provide for singlepoint-to-multipoint
1673 intent via cli
1674 """
1675 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001676 cmd = "add-single-to-multi-intent"
kelvin-onlabb9408212015-04-01 13:34:04 -07001677
Jeremy Songsterff553672016-05-12 17:06:23 -07001678 if ethType:
1679 cmd += " --ethType " + str( ethType )
1680 if ethSrc:
1681 cmd += " --ethSrc " + str( ethSrc )
1682 if ethDst:
1683 cmd += " --ethDst " + str( ethDst )
1684 if bandwidth:
1685 cmd += " --bandwidth " + str( bandwidth )
1686 if lambdaAlloc:
1687 cmd += " --lambda "
1688 if ipProto:
1689 cmd += " --ipProto " + str( ipProto )
1690 if ipSrc:
1691 cmd += " --ipSrc " + str( ipSrc )
1692 if ipDst:
1693 cmd += " --ipDst " + str( ipDst )
1694 if tcpSrc:
1695 cmd += " --tcpSrc " + str( tcpSrc )
1696 if tcpDst:
1697 cmd += " --tcpDst " + str( tcpDst )
1698 if setEthSrc:
1699 cmd += " --setEthSrc " + str( setEthSrc )
1700 if setEthDst:
1701 cmd += " --setEthDst " + str( setEthDst )
1702 if vlanId:
1703 cmd += " -v " + str( vlanId )
1704 if setVlan:
1705 cmd += " --setVlan " + str( setVlan )
Jeremy Songster9385d412016-06-02 17:57:36 -07001706 if partial:
1707 cmd += " --partial"
Jeremy Songsterc032f162016-08-04 17:14:49 -07001708 if encap:
1709 cmd += " --encapsulation " + str( encap )
kelvin-onlabb9408212015-04-01 13:34:04 -07001710
1711 # Check whether the user appended the port
1712 # or provided it as an input
Jon Hall08f61bc2015-04-13 16:00:30 -07001713
kelvin-onlabb9408212015-04-01 13:34:04 -07001714 if "/" in ingressDevice:
1715 cmd += " " + str( ingressDevice )
1716 else:
1717 if not portIngress:
1718 main.log.error( "You must specify " +
1719 "the Ingress port" )
1720 return main.FALSE
1721
1722 cmd += " " +\
1723 str( ingressDevice ) + "/" +\
1724 str( portIngress )
1725
1726 if portEgressList is None:
1727 for egressDevice in egressDeviceList:
1728 if "/" in egressDevice:
1729 cmd += " " + str( egressDevice )
1730 else:
1731 main.log.error( "You must specify " +
1732 "the egress port" )
1733 # TODO: perhaps more meaningful return
1734 return main.FALSE
1735 else:
1736 if len( egressDeviceList ) == len( portEgressList ):
Jon Hall08f61bc2015-04-13 16:00:30 -07001737 for egressDevice, portEgress in zip( egressDeviceList,
1738 portEgressList ):
kelvin-onlabb9408212015-04-01 13:34:04 -07001739 cmd += " " + \
1740 str( egressDevice ) + "/" +\
1741 str( portEgress )
kelvin-onlab38143812015-04-01 15:03:01 -07001742 else:
Jon Hall08f61bc2015-04-13 16:00:30 -07001743 main.log.error( "Device list and port list does not " +
1744 "have the same length" )
kelvin-onlab38143812015-04-01 15:03:01 -07001745 return main.FALSE
kelvin-onlabb9408212015-04-01 13:34:04 -07001746 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001747 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001748 assert "Command not found:" not in handle, handle
kelvin-onlabb9408212015-04-01 13:34:04 -07001749 # If error, return error message
1750 if re.search( "Error", handle ):
1751 main.log.error( "Error in adding singlepoint-to-multipoint " +
1752 "intent" )
shahshreyac2f97072015-03-19 17:04:29 -07001753 return None
kelvin-onlabb9408212015-04-01 13:34:04 -07001754 else:
1755 match = re.search('id=0x([\da-f]+),', handle)
1756 if match:
1757 return match.group()[3:-1]
1758 else:
1759 main.log.error( "Error, intent ID not found" )
1760 return None
Jon Hallc6793552016-01-19 14:18:37 -08001761 except AssertionError:
1762 main.log.exception( "" )
1763 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001764 except TypeError:
1765 main.log.exception( self.name + ": Object not as expected" )
1766 return None
shahshreyad0c80432014-12-04 16:56:05 -08001767 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001768 main.log.error( self.name + ": EOF exception found" )
1769 main.log.error( self.name + ": " + self.handle.before )
shahshreyad0c80432014-12-04 16:56:05 -08001770 main.cleanup()
1771 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001772 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001773 main.log.exception( self.name + ": Uncaught exception!" )
shahshreyad0c80432014-12-04 16:56:05 -08001774 main.cleanup()
1775 main.exit()
1776
Hari Krishna9e232602015-04-13 17:29:08 -07001777 def addMplsIntent(
1778 self,
1779 ingressDevice,
1780 egressDevice,
Hari Krishna87a17f12015-04-13 17:42:23 -07001781 ingressPort="",
1782 egressPort="",
Hari Krishna9e232602015-04-13 17:29:08 -07001783 ethType="",
1784 ethSrc="",
1785 ethDst="",
1786 bandwidth="",
1787 lambdaAlloc=False,
1788 ipProto="",
1789 ipSrc="",
1790 ipDst="",
1791 tcpSrc="",
1792 tcpDst="",
Hari Krishna87a17f12015-04-13 17:42:23 -07001793 ingressLabel="",
Hari Krishnadfff6672015-04-13 17:53:27 -07001794 egressLabel="",
Hari Krishna9e232602015-04-13 17:29:08 -07001795 priority=""):
1796 """
1797 Required:
1798 * ingressDevice: device id of ingress device
1799 * egressDevice: device id of egress device
1800 Optional:
1801 * ethType: specify ethType
1802 * ethSrc: specify ethSrc ( i.e. src mac addr )
1803 * ethDst: specify ethDst ( i.e. dst mac addr )
1804 * bandwidth: specify bandwidth capacity of link
1805 * lambdaAlloc: if True, intent will allocate lambda
1806 for the specified intent
1807 * ipProto: specify ip protocol
1808 * ipSrc: specify ip source address
1809 * ipDst: specify ip destination address
1810 * tcpSrc: specify tcp source port
1811 * tcpDst: specify tcp destination port
1812 * ingressLabel: Ingress MPLS label
1813 * egressLabel: Egress MPLS label
1814 Description:
1815 Adds MPLS intent by
1816 specifying device id's and optional fields
1817 Returns:
1818 A string of the intent id or None on error
1819
1820 NOTE: This function may change depending on the
1821 options developers provide for MPLS
1822 intent via cli
1823 """
1824 try:
Jeremy Songsterff553672016-05-12 17:06:23 -07001825 cmd = "add-mpls-intent"
Hari Krishna9e232602015-04-13 17:29:08 -07001826
Jeremy Songsterff553672016-05-12 17:06:23 -07001827 if ethType:
1828 cmd += " --ethType " + str( ethType )
1829 if ethSrc:
1830 cmd += " --ethSrc " + str( ethSrc )
1831 if ethDst:
1832 cmd += " --ethDst " + str( ethDst )
1833 if bandwidth:
1834 cmd += " --bandwidth " + str( bandwidth )
1835 if lambdaAlloc:
1836 cmd += " --lambda "
1837 if ipProto:
1838 cmd += " --ipProto " + str( ipProto )
1839 if ipSrc:
1840 cmd += " --ipSrc " + str( ipSrc )
1841 if ipDst:
1842 cmd += " --ipDst " + str( ipDst )
1843 if tcpSrc:
1844 cmd += " --tcpSrc " + str( tcpSrc )
1845 if tcpDst:
1846 cmd += " --tcpDst " + str( tcpDst )
1847 if ingressLabel:
1848 cmd += " --ingressLabel " + str( ingressLabel )
1849 if egressLabel:
1850 cmd += " --egressLabel " + str( egressLabel )
1851 if priority:
1852 cmd += " --priority " + str( priority )
Hari Krishna9e232602015-04-13 17:29:08 -07001853
1854 # Check whether the user appended the port
1855 # or provided it as an input
1856 if "/" in ingressDevice:
1857 cmd += " " + str( ingressDevice )
1858 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001859 if not ingressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001860 main.log.error( "You must specify the ingress port" )
1861 return None
1862
1863 cmd += " " + \
1864 str( ingressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001865 str( ingressPort ) + " "
Hari Krishna9e232602015-04-13 17:29:08 -07001866
1867 if "/" in egressDevice:
1868 cmd += " " + str( egressDevice )
1869 else:
Hari Krishna87a17f12015-04-13 17:42:23 -07001870 if not egressPort:
Hari Krishna9e232602015-04-13 17:29:08 -07001871 main.log.error( "You must specify the egress port" )
1872 return None
1873
1874 cmd += " " +\
1875 str( egressDevice ) + "/" +\
Hari Krishna87a17f12015-04-13 17:42:23 -07001876 str( egressPort )
Hari Krishna9e232602015-04-13 17:29:08 -07001877
1878 handle = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08001879 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001880 assert "Command not found:" not in handle, handle
Hari Krishna9e232602015-04-13 17:29:08 -07001881 # If error, return error message
1882 if re.search( "Error", handle ):
1883 main.log.error( "Error in adding mpls intent" )
1884 return None
1885 else:
1886 # TODO: print out all the options in this message?
1887 main.log.info( "MPLS intent installed between " +
1888 str( ingressDevice ) + " and " +
1889 str( egressDevice ) )
1890 match = re.search('id=0x([\da-f]+),', handle)
1891 if match:
1892 return match.group()[3:-1]
1893 else:
1894 main.log.error( "Error, intent ID not found" )
1895 return None
Jon Hallc6793552016-01-19 14:18:37 -08001896 except AssertionError:
1897 main.log.exception( "" )
1898 return None
Hari Krishna9e232602015-04-13 17:29:08 -07001899 except TypeError:
1900 main.log.exception( self.name + ": Object not as expected" )
1901 return None
1902 except pexpect.EOF:
1903 main.log.error( self.name + ": EOF exception found" )
1904 main.log.error( self.name + ": " + self.handle.before )
1905 main.cleanup()
1906 main.exit()
1907 except Exception:
1908 main.log.exception( self.name + ": Uncaught exception!" )
1909 main.cleanup()
1910 main.exit()
1911
Jon Hallefbd9792015-03-05 16:11:36 -08001912 def removeIntent( self, intentId, app='org.onosproject.cli',
1913 purge=False, sync=False ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001914 """
shahshreya1c818fc2015-02-26 13:44:08 -08001915 Remove intent for specified application id and intent id
Jon Hall61282e32015-03-19 11:34:11 -07001916 Optional args:-
shahshreya1c818fc2015-02-26 13:44:08 -08001917 -s or --sync: Waits for the removal before returning
Jon Hall61282e32015-03-19 11:34:11 -07001918 -p or --purge: Purge the intent from the store after removal
1919
Jon Halle3f39ff2015-01-13 11:50:53 -08001920 Returns:
Jon Hall6509dbf2016-06-21 17:01:17 -07001921 main.FALSE on error and
Jon Halle3f39ff2015-01-13 11:50:53 -08001922 cli output otherwise
kelvin-onlab898a6c62015-01-16 14:13:53 -08001923 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04001924 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07001925 cmdStr = "remove-intent"
shahshreya1c818fc2015-02-26 13:44:08 -08001926 if purge:
1927 cmdStr += " -p"
1928 if sync:
1929 cmdStr += " -s"
1930
1931 cmdStr += " " + app + " " + str( intentId )
kelvin-onlabd3b64892015-01-20 13:26:24 -08001932 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08001933 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08001934 assert "Command not found:" not in handle, handle
Jon Halle3f39ff2015-01-13 11:50:53 -08001935 if re.search( "Error", handle ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08001936 main.log.error( "Error in removing intent" )
Jon Halle3f39ff2015-01-13 11:50:53 -08001937 return main.FALSE
andrewonlab9a50dfe2014-10-17 17:22:31 -04001938 else:
Jon Halle3f39ff2015-01-13 11:50:53 -08001939 # TODO: Should this be main.TRUE
1940 return handle
Jon Hallc6793552016-01-19 14:18:37 -08001941 except AssertionError:
1942 main.log.exception( "" )
1943 return None
Jon Halld4d4b372015-01-28 16:02:41 -08001944 except TypeError:
1945 main.log.exception( self.name + ": Object not as expected" )
1946 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04001947 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08001948 main.log.error( self.name + ": EOF exception found" )
1949 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001950 main.cleanup()
1951 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08001952 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08001953 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04001954 main.cleanup()
1955 main.exit()
1956
YPZhangfebf7302016-05-24 16:45:56 -07001957 def removeAllIntents( self, purge=False, sync=False, app='org.onosproject.cli', timeout=30 ):
Jeremy42df2e72016-02-23 16:37:46 -08001958 """
1959 Description:
1960 Remove all the intents
1961 Optional args:-
1962 -s or --sync: Waits for the removal before returning
1963 -p or --purge: Purge the intent from the store after removal
1964 Returns:
1965 Returns main.TRUE if all intents are removed, otherwise returns
1966 main.FALSE; Returns None for exception
1967 """
1968 try:
1969 cmdStr = "remove-intent"
1970 if purge:
1971 cmdStr += " -p"
1972 if sync:
1973 cmdStr += " -s"
1974
1975 cmdStr += " " + app
YPZhangfebf7302016-05-24 16:45:56 -07001976 handle = self.sendline( cmdStr, timeout=timeout )
You Wangb5a55f72017-03-03 12:51:05 -08001977 assert handle is not None, "Error in sendline"
Jeremy42df2e72016-02-23 16:37:46 -08001978 assert "Command not found:" not in handle, handle
1979 if re.search( "Error", handle ):
1980 main.log.error( "Error in removing intent" )
1981 return main.FALSE
1982 else:
1983 return main.TRUE
1984 except AssertionError:
1985 main.log.exception( "" )
1986 return None
1987 except TypeError:
1988 main.log.exception( self.name + ": Object not as expected" )
1989 return None
1990 except pexpect.EOF:
1991 main.log.error( self.name + ": EOF exception found" )
1992 main.log.error( self.name + ": " + self.handle.before )
1993 main.cleanup()
1994 main.exit()
1995 except Exception:
1996 main.log.exception( self.name + ": Uncaught exception!" )
1997 main.cleanup()
1998 main.exit()
1999
Hari Krishnaacabd5a2015-07-01 17:10:19 -07002000 def purgeWithdrawnIntents( self ):
Hari Krishna0ce0e152015-06-23 09:55:29 -07002001 """
2002 Purges all WITHDRAWN Intents
2003 """
2004 try:
2005 cmdStr = "purge-intents"
2006 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002007 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002008 assert "Command not found:" not in handle, handle
Hari Krishna0ce0e152015-06-23 09:55:29 -07002009 if re.search( "Error", handle ):
2010 main.log.error( "Error in purging intents" )
2011 return main.FALSE
2012 else:
2013 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002014 except AssertionError:
2015 main.log.exception( "" )
2016 return None
Hari Krishna0ce0e152015-06-23 09:55:29 -07002017 except TypeError:
2018 main.log.exception( self.name + ": Object not as expected" )
2019 return None
2020 except pexpect.EOF:
2021 main.log.error( self.name + ": EOF exception found" )
2022 main.log.error( self.name + ": " + self.handle.before )
2023 main.cleanup()
2024 main.exit()
2025 except Exception:
2026 main.log.exception( self.name + ": Uncaught exception!" )
2027 main.cleanup()
2028 main.exit()
2029
kelvin-onlabd3b64892015-01-20 13:26:24 -08002030 def routes( self, jsonFormat=False ):
kelvin8ec71442015-01-15 16:57:00 -08002031 """
kelvin-onlab898a6c62015-01-16 14:13:53 -08002032 NOTE: This method should be used after installing application:
2033 onos-app-sdnip
pingping-lin8b306ac2014-11-17 18:13:51 -08002034 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002035 * jsonFormat: enable output formatting in json
pingping-lin8b306ac2014-11-17 18:13:51 -08002036 Description:
2037 Obtain all routes in the system
kelvin8ec71442015-01-15 16:57:00 -08002038 """
pingping-lin8b306ac2014-11-17 18:13:51 -08002039 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002040 cmdStr = "routes"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002041 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002042 cmdStr += " -j"
2043 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002044 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002045 assert "Command not found:" not in handle, handle
pingping-lin8b306ac2014-11-17 18:13:51 -08002046 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002047 except AssertionError:
2048 main.log.exception( "" )
2049 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002050 except TypeError:
2051 main.log.exception( self.name + ": Object not as expected" )
2052 return None
pingping-lin8b306ac2014-11-17 18:13:51 -08002053 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002054 main.log.error( self.name + ": EOF exception found" )
2055 main.log.error( self.name + ": " + self.handle.before )
pingping-lin8b306ac2014-11-17 18:13:51 -08002056 main.cleanup()
2057 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002058 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002059 main.log.exception( self.name + ": Uncaught exception!" )
pingping-lin8b306ac2014-11-17 18:13:51 -08002060 main.cleanup()
2061 main.exit()
2062
pingping-lin54b03372015-08-13 14:43:10 -07002063 def ipv4RouteNumber( self ):
2064 """
2065 NOTE: This method should be used after installing application:
2066 onos-app-sdnip
2067 Description:
2068 Obtain the total IPv4 routes number in the system
2069 """
2070 try:
Pratik Parab57963572017-05-09 11:37:54 -07002071 cmdStr = "routes -j"
pingping-lin54b03372015-08-13 14:43:10 -07002072 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002073 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002074 assert "Command not found:" not in handle, handle
pingping-lin54b03372015-08-13 14:43:10 -07002075 jsonResult = json.loads( handle )
Pratik Parab57963572017-05-09 11:37:54 -07002076 return len(jsonResult['routes4'])
Jon Hallc6793552016-01-19 14:18:37 -08002077 except AssertionError:
2078 main.log.exception( "" )
2079 return None
2080 except ( TypeError, ValueError ):
2081 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002082 return None
2083 except pexpect.EOF:
2084 main.log.error( self.name + ": EOF exception found" )
2085 main.log.error( self.name + ": " + self.handle.before )
2086 main.cleanup()
2087 main.exit()
2088 except Exception:
2089 main.log.exception( self.name + ": Uncaught exception!" )
2090 main.cleanup()
2091 main.exit()
2092
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002093 #=============Function to check Bandwidth allocation========
2094 def allocations( self, jsonFormat = True, dollarSign = True ):
2095 """
2096 Description:
2097 Obtain Bandwidth Allocation Information from ONOS cli.
2098 """
2099 try:
2100 cmdStr = "allocations"
2101 if jsonFormat:
2102 cmdStr += " -j"
2103 handle = self.sendline( cmdStr, timeout=300, dollarSign=True )
2104 assert handle is not None, "Error in sendline"
2105 assert "Command not found:" not in handle, handle
2106 return handle
2107 except AssertionError:
2108 main.log.exception( "" )
2109 return None
2110 except ( TypeError, ValueError ):
2111 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
2112 return None
2113 except pexpect.EOF:
2114 main.log.error( self.name + ": EOF exception found" )
2115 main.log.error( self.name + ": " + self.handle.before )
2116 main.cleanup()
2117 main.exit()
2118 except Exception:
2119 main.log.exception( self.name + ": Uncaught exception!" )
2120 main.cleanup()
2121 main.exit()
2122
pingping-lin8244a3b2015-09-16 13:36:56 -07002123 def intents( self, jsonFormat = True, summary = False, **intentargs):
kelvin8ec71442015-01-15 16:57:00 -08002124 """
andrewonlabe6745342014-10-17 14:29:13 -04002125 Description:
Jon Hallff566d52016-01-15 14:45:36 -08002126 Obtain intents from the ONOS cli.
2127 Optional:
2128 * jsonFormat: Enable output formatting in json, default to True
2129 * summary: Whether only output the intent summary, defaults to False
2130 * type: Only output a certain type of intent. This options is valid
2131 only when jsonFormat is True and summary is True.
kelvin-onlab898a6c62015-01-16 14:13:53 -08002132 """
andrewonlabe6745342014-10-17 14:29:13 -04002133 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002134 cmdStr = "intents"
pingping-lin8244a3b2015-09-16 13:36:56 -07002135 if summary:
2136 cmdStr += " -s"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002137 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002138 cmdStr += " -j"
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002139 handle = self.sendline( cmdStr, timeout=300 )
You Wangb5a55f72017-03-03 12:51:05 -08002140 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002141 assert "Command not found:" not in handle, handle
pingping-lin8244a3b2015-09-16 13:36:56 -07002142 args = utilities.parse_args( [ "TYPE" ], **intentargs )
acsmars5b5fbaf2015-09-18 10:38:20 -07002143 if "TYPE" in args.keys():
Jon Hallff566d52016-01-15 14:45:36 -08002144 intentType = args[ "TYPE" ]
acsmars5b5fbaf2015-09-18 10:38:20 -07002145 else:
Jon Hallff566d52016-01-15 14:45:36 -08002146 intentType = ""
2147 # IF we want the summary of a specific intent type
2148 if jsonFormat and summary and ( intentType != "" ):
pingping-lin8244a3b2015-09-16 13:36:56 -07002149 jsonResult = json.loads( handle )
Jon Hallff566d52016-01-15 14:45:36 -08002150 if intentType in jsonResult.keys():
2151 return jsonResult[ intentType ]
pingping-lin8244a3b2015-09-16 13:36:56 -07002152 else:
Jon Hallff566d52016-01-15 14:45:36 -08002153 main.log.error( "unknown TYPE, returning all types of intents" )
pingping-lin8244a3b2015-09-16 13:36:56 -07002154 return handle
2155 else:
2156 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002157 except AssertionError:
2158 main.log.exception( "" )
2159 return None
2160 except ( TypeError, ValueError ):
2161 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, handle ) )
pingping-lin54b03372015-08-13 14:43:10 -07002162 return None
2163 except pexpect.EOF:
2164 main.log.error( self.name + ": EOF exception found" )
2165 main.log.error( self.name + ": " + self.handle.before )
2166 main.cleanup()
2167 main.exit()
2168 except Exception:
2169 main.log.exception( self.name + ": Uncaught exception!" )
2170 main.cleanup()
2171 main.exit()
2172
kelvin-onlab54400a92015-02-26 18:05:51 -08002173 def getIntentState(self, intentsId, intentsJson=None):
2174 """
You Wangfdcbfc42016-05-16 12:16:53 -07002175 Description:
2176 Gets intent state. Accepts a single intent ID (string type) or a
2177 list of intent IDs.
2178 Parameters:
2179 intentsId: intent ID, both string type and list type are acceptable
kelvin-onlab54400a92015-02-26 18:05:51 -08002180 intentsJson: parsed json object from the onos:intents api
You Wangfdcbfc42016-05-16 12:16:53 -07002181 Returns:
2182 Returns the state (string type) of the ID if a single intent ID is
2183 accepted.
2184 Returns a list of dictionaries if a list of intent IDs is accepted,
2185 and each dictionary maps 'id' to the Intent ID and 'state' to
2186 corresponding intent state.
kelvin-onlab54400a92015-02-26 18:05:51 -08002187 """
Shreya Chowdhary6fbb96c2017-05-02 16:20:19 -07002188
kelvin-onlab54400a92015-02-26 18:05:51 -08002189 try:
2190 state = "State is Undefined"
2191 if not intentsJson:
Jon Hallc6793552016-01-19 14:18:37 -08002192 rawJson = self.intents()
kelvin-onlab54400a92015-02-26 18:05:51 -08002193 else:
Jon Hallc6793552016-01-19 14:18:37 -08002194 rawJson = intentsJson
2195 parsedIntentsJson = json.loads( rawJson )
Jon Hallefbd9792015-03-05 16:11:36 -08002196 if isinstance( intentsId, types.StringType ):
Jon Hallc6793552016-01-19 14:18:37 -08002197 for intent in parsedIntentsJson:
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002198 if intentsId == intent[ 'id' ]:
2199 state = intent[ 'state' ]
kelvin-onlab54400a92015-02-26 18:05:51 -08002200 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002201 main.log.info( "Cannot find intent ID" + str( intentsId ) +
Jon Hall53158082017-05-18 11:17:00 -07002202 " in the list" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002203 return state
Jon Hallefbd9792015-03-05 16:11:36 -08002204 elif isinstance( intentsId, types.ListType ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002205 dictList = []
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002206 for i in xrange( len( intentsId ) ):
kelvin-onlab07dbd012015-03-04 16:29:39 -08002207 stateDict = {}
Jon Hall53158082017-05-18 11:17:00 -07002208 for intent in parsedIntentsJson:
2209 if intentsId[ i ] == intent[ 'id' ]:
2210 stateDict[ 'state' ] = intent[ 'state' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002211 stateDict[ 'id' ] = intentsId[ i ]
Jon Hallefbd9792015-03-05 16:11:36 -08002212 dictList.append( stateDict )
kelvin-onlab54400a92015-02-26 18:05:51 -08002213 break
Jon Hallefbd9792015-03-05 16:11:36 -08002214 if len( intentsId ) != len( dictList ):
Jon Hall53158082017-05-18 11:17:00 -07002215 main.log.warn( "Could not find all intents in ONOS output" )
2216 main.log.debug( "expected ids: {} \n ONOS intents: {}".format( intentsId, parsedIntentsJson ) )
kelvin-onlab07dbd012015-03-04 16:29:39 -08002217 return dictList
kelvin-onlab54400a92015-02-26 18:05:51 -08002218 else:
Jon Hall53158082017-05-18 11:17:00 -07002219 main.log.info( "Invalid type for intentsId argument" )
kelvin-onlab54400a92015-02-26 18:05:51 -08002220 return None
Jon Hallc6793552016-01-19 14:18:37 -08002221 except ( TypeError, ValueError ):
2222 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
kelvin-onlab54400a92015-02-26 18:05:51 -08002223 return None
2224 except pexpect.EOF:
2225 main.log.error( self.name + ": EOF exception found" )
2226 main.log.error( self.name + ": " + self.handle.before )
2227 main.cleanup()
2228 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002229 except Exception:
kelvin-onlab54400a92015-02-26 18:05:51 -08002230 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlabe6745342014-10-17 14:29:13 -04002231 main.cleanup()
2232 main.exit()
Jon Hall390696c2015-05-05 17:13:41 -07002233
Jon Hallf539eb92017-05-22 17:18:42 -07002234 def checkIntentState( self, intentsId, expectedState='INSTALLED' ):
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002235 """
2236 Description:
2237 Check intents state
2238 Required:
2239 intentsId - List of intents ID to be checked
2240 Optional:
kelvin-onlabf512e942015-06-08 19:42:59 -07002241 expectedState - Check the expected state(s) of each intents
2242 state in the list.
2243 *NOTE: You can pass in a list of expected state,
2244 Eg: expectedState = [ 'INSTALLED' , 'INSTALLING' ]
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002245 Return:
Jon Hall53158082017-05-18 11:17:00 -07002246 Returns main.TRUE only if all intent are the same as expected states,
2247 otherwise returns main.FALSE.
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002248 """
2249 try:
kelvin-onlabf512e942015-06-08 19:42:59 -07002250 returnValue = main.TRUE
Jon Hallf539eb92017-05-22 17:18:42 -07002251 # Generating a dictionary: intent id as a key and state as value
Devin Lim752dd7b2017-06-27 14:40:03 -07002252
2253 #intentsDict = self.getIntentState( intentsId )
2254 intentsDict = []
2255 for intent in json.loads( self.intents() ):
2256 if isinstance ( intentsId, types.StringType) \
2257 and intent.get('id') == intentsId:
2258 intentsDict.append(intent)
2259 elif isinstance ( intentsId, types.ListType ) \
2260 and any( intent.get( 'id' ) == ids for ids in intentsId ):
2261 intentsDict.append(intent)
2262
2263 if not intentsDict:
Jon Hallae04e622016-01-27 10:38:05 -08002264 main.log.info( self.name + ": There is something wrong " +
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002265 "getting intents state" )
2266 return main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002267
2268 if isinstance( expectedState, types.StringType ):
2269 for intents in intentsDict:
2270 if intents.get( 'state' ) != expectedState:
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002271 main.log.debug( self.name + " : Intent ID - " +
2272 intents.get( 'id' ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002273 " actual state = " +
2274 intents.get( 'state' )
2275 + " does not equal expected state = "
2276 + expectedState )
kelvin-onlaba297c4d2015-06-01 13:53:55 -07002277 returnValue = main.FALSE
kelvin-onlabf512e942015-06-08 19:42:59 -07002278 elif isinstance( expectedState, types.ListType ):
2279 for intents in intentsDict:
2280 if not any( state == intents.get( 'state' ) for state in
2281 expectedState ):
2282 main.log.debug( self.name + " : Intent ID - " +
2283 intents.get( 'id' ) +
2284 " actual state = " +
2285 intents.get( 'state' ) +
2286 " does not equal expected states = "
2287 + str( expectedState ) )
2288 returnValue = main.FALSE
2289
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002290 if returnValue == main.TRUE:
2291 main.log.info( self.name + ": All " +
2292 str( len( intentsDict ) ) +
kelvin-onlabf512e942015-06-08 19:42:59 -07002293 " intents are in " + str( expectedState ) +
2294 " state" )
kelvin-onlabc2dcd3f2015-04-09 16:40:02 -07002295 return returnValue
2296 except TypeError:
2297 main.log.exception( self.name + ": Object not as expected" )
2298 return None
2299 except pexpect.EOF:
2300 main.log.error( self.name + ": EOF exception found" )
2301 main.log.error( self.name + ": " + self.handle.before )
2302 main.cleanup()
2303 main.exit()
2304 except Exception:
2305 main.log.exception( self.name + ": Uncaught exception!" )
2306 main.cleanup()
2307 main.exit()
andrewonlabe6745342014-10-17 14:29:13 -04002308
Jon Hallf539eb92017-05-22 17:18:42 -07002309 def compareBandwidthAllocations( self, expectedAllocations ):
2310 """
2311 Description:
2312 Compare the allocated bandwidth with the given allocations
2313 Required:
2314 expectedAllocations - The expected ONOS output of the allocations command
2315 Return:
2316 Returns main.TRUE only if all intent are the same as expected states,
2317 otherwise returns main.FALSE.
2318 """
2319 # FIXME: Convert these string comparisons to object comparisons
2320 try:
2321 returnValue = main.TRUE
2322 bandwidthFailed = False
2323 rawAlloc = self.allocations()
2324 expectedFormat = StringIO( expectedAllocations )
2325 ONOSOutput = StringIO( rawAlloc )
2326 main.log.debug( "ONOSOutput: {}\nexpected output: {}".format( str( ONOSOutput ),
2327 str( expectedFormat ) ) )
2328
2329 for actual, expected in izip( ONOSOutput, expectedFormat ):
2330 actual = actual.rstrip()
2331 expected = expected.rstrip()
2332 main.log.debug( "Expect: {}\nactual: {}".format( expected, actual ) )
2333 if actual != expected and 'allocated' in actual and 'allocated' in expected:
2334 marker1 = actual.find('allocated')
2335 m1 = actual[:marker1]
2336 marker2 = expected.find('allocated')
2337 m2 = expected[:marker2]
2338 if m1 != m2:
2339 bandwidthFailed = True
2340 elif actual != expected and 'allocated' not in actual and 'allocated' not in expected:
2341 bandwidthFailed = True
2342 expectedFormat.close()
2343 ONOSOutput.close()
2344
2345 if bandwidthFailed:
2346 main.log.error("Bandwidth not allocated correctly using Intents!!")
2347 returnValue = main.FALSE
2348 return returnValue
2349 except TypeError:
2350 main.log.exception( self.name + ": Object not as expected" )
2351 return None
2352 except pexpect.EOF:
2353 main.log.error( self.name + ": EOF exception found" )
2354 main.log.error( self.name + ": " + self.handle.before )
2355 main.cleanup()
2356 main.exit()
2357 except Exception:
2358 main.log.exception( self.name + ": Uncaught exception!" )
2359 main.cleanup()
2360 main.exit()
2361
You Wang66518af2016-05-16 15:32:59 -07002362 def compareIntent( self, intentDict ):
2363 """
2364 Description:
2365 Compare the intent ids and states provided in the argument with all intents in ONOS
2366 Return:
2367 Returns main.TRUE if the two sets of intents match exactly, otherwise main.FALSE
2368 Arguments:
2369 intentDict: a dictionary which maps intent ids to intent states
2370 """
2371 try:
2372 intentsRaw = self.intents()
2373 intentsJson = json.loads( intentsRaw )
2374 intentDictONOS = {}
2375 for intent in intentsJson:
2376 intentDictONOS[ intent[ 'id' ] ] = intent[ 'state' ]
You Wang58d04452016-09-21 15:13:05 -07002377 returnValue = main.TRUE
You Wang66518af2016-05-16 15:32:59 -07002378 if len( intentDict ) != len( intentDictONOS ):
You Wang58d04452016-09-21 15:13:05 -07002379 main.log.warn( self.name + ": expected intent count does not match that in ONOS, " +
You Wang66518af2016-05-16 15:32:59 -07002380 str( len( intentDict ) ) + " expected and " +
2381 str( len( intentDictONOS ) ) + " actual" )
You Wang58d04452016-09-21 15:13:05 -07002382 returnValue = main.FALSE
You Wang66518af2016-05-16 15:32:59 -07002383 for intentID in intentDict.keys():
Jon Halle0f0b342017-04-18 11:43:47 -07002384 if intentID not in intentDictONOS.keys():
You Wang66518af2016-05-16 15:32:59 -07002385 main.log.debug( self.name + ": intent ID - " + intentID + " is not in ONOS" )
2386 returnValue = main.FALSE
You Wang58d04452016-09-21 15:13:05 -07002387 else:
2388 if intentDict[ intentID ] != intentDictONOS[ intentID ]:
2389 main.log.debug( self.name + ": intent ID - " + intentID +
2390 " expected state is " + intentDict[ intentID ] +
2391 " but actual state is " + intentDictONOS[ intentID ] )
2392 returnValue = main.FALSE
2393 intentDictONOS.pop( intentID )
2394 if len( intentDictONOS ) > 0:
2395 returnValue = main.FALSE
2396 for intentID in intentDictONOS.keys():
2397 main.log.debug( self.name + ": find extra intent in ONOS: intent ID " + intentID )
You Wang66518af2016-05-16 15:32:59 -07002398 if returnValue == main.TRUE:
2399 main.log.info( self.name + ": all intent IDs and states match that in ONOS" )
2400 return returnValue
You Wang1be9a512016-05-26 16:54:17 -07002401 except KeyError:
2402 main.log.exception( self.name + ": KeyError exception found" )
2403 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002404 except ( TypeError, ValueError ):
2405 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intentsRaw ) )
You Wang85560372016-05-18 10:44:33 -07002406 return main.ERROR
You Wang66518af2016-05-16 15:32:59 -07002407 except pexpect.EOF:
2408 main.log.error( self.name + ": EOF exception found" )
2409 main.log.error( self.name + ": " + self.handle.before )
2410 main.cleanup()
2411 main.exit()
2412 except Exception:
2413 main.log.exception( self.name + ": Uncaught exception!" )
2414 main.cleanup()
2415 main.exit()
2416
YPZhang14a4aa92016-07-15 13:37:15 -07002417 def checkIntentSummary( self, timeout=60, noExit=True ):
GlennRCed771242016-01-13 17:02:47 -08002418 """
2419 Description:
2420 Check the number of installed intents.
2421 Optional:
2422 timeout - the timeout for pexcept
YPZhang14a4aa92016-07-15 13:37:15 -07002423 noExit - If noExit, TestON will not exit if any except.
GlennRCed771242016-01-13 17:02:47 -08002424 Return:
2425 Returns main.TRUE only if the number of all installed intents are the same as total intents number
2426 , otherwise, returns main.FALSE.
2427 """
2428
2429 try:
2430 cmd = "intents -s -j"
2431
2432 # Check response if something wrong
YPZhang14a4aa92016-07-15 13:37:15 -07002433 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002434 if response is None:
YPZhang0584d432016-06-21 15:20:13 -07002435 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002436 response = json.loads( response )
2437
2438 # get total and installed number, see if they are match
2439 allState = response.get( 'all' )
2440 if allState.get('total') == allState.get('installed'):
YPZhangb5d3f832016-01-23 22:54:26 -08002441 main.log.info( 'Total Intents: {} Installed Intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002442 return main.TRUE
YPZhangb5d3f832016-01-23 22:54:26 -08002443 main.log.info( 'Verified Intents failed Excepte intetnes: {} installed intents: {}'.format( allState.get('total'), allState.get('installed') ) )
GlennRCed771242016-01-13 17:02:47 -08002444 return main.FALSE
2445
Jon Hallc6793552016-01-19 14:18:37 -08002446 except ( TypeError, ValueError ):
2447 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
GlennRCed771242016-01-13 17:02:47 -08002448 return None
2449 except pexpect.EOF:
2450 main.log.error( self.name + ": EOF exception found" )
2451 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002452 if noExit:
2453 return main.FALSE
2454 else:
2455 main.cleanup()
2456 main.exit()
Jon Halle0f0b342017-04-18 11:43:47 -07002457 except pexpect.TIMEOUT:
2458 main.log.error( self.name + ": ONOS timeout" )
2459 return None
GlennRCed771242016-01-13 17:02:47 -08002460 except Exception:
2461 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002462 if noExit:
2463 return main.FALSE
2464 else:
2465 main.cleanup()
2466 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002467
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002468 def flows( self, state="", jsonFormat=True, timeout=60, noExit=False, noCore=False ):
kelvin8ec71442015-01-15 16:57:00 -08002469 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002470 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002471 * jsonFormat: enable output formatting in json
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002472 * noCore: suppress core flows
Shreya Shah0f01c812014-10-26 20:15:28 -04002473 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002474 Obtain flows currently installed
kelvin-onlab898a6c62015-01-16 14:13:53 -08002475 """
Shreya Shah0f01c812014-10-26 20:15:28 -04002476 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002477 cmdStr = "flows"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002478 if jsonFormat:
GlennRCed771242016-01-13 17:02:47 -08002479 cmdStr += " -j "
Jeremy Songster306ed7a2016-07-19 10:59:07 -07002480 if noCore:
2481 cmdStr += " -n "
GlennRCed771242016-01-13 17:02:47 -08002482 cmdStr += state
YPZhangebf9eb52016-05-12 15:20:24 -07002483 handle = self.sendline( cmdStr, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002484 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002485 assert "Command not found:" not in handle, handle
2486 if re.search( "Error:", handle ):
2487 main.log.error( self.name + ": flows() response: " +
2488 str( handle ) )
2489 return handle
2490 except AssertionError:
2491 main.log.exception( "" )
GlennRCed771242016-01-13 17:02:47 -08002492 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002493 except TypeError:
2494 main.log.exception( self.name + ": Object not as expected" )
2495 return None
Jon Hallc6793552016-01-19 14:18:37 -08002496 except pexpect.TIMEOUT:
2497 main.log.error( self.name + ": ONOS timeout" )
2498 return None
Shreya Shah0f01c812014-10-26 20:15:28 -04002499 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002500 main.log.error( self.name + ": EOF exception found" )
2501 main.log.error( self.name + ": " + self.handle.before )
Shreya Shah0f01c812014-10-26 20:15:28 -04002502 main.cleanup()
2503 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002504 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002505 main.log.exception( self.name + ": Uncaught exception!" )
Shreya Shah0f01c812014-10-26 20:15:28 -04002506 main.cleanup()
2507 main.exit()
2508
Flavio Castrod2ffffa2016-04-26 15:56:56 -07002509 def checkFlowCount(self, min=0, timeout=60 ):
Flavio Castroa1286fe2016-07-25 14:48:51 -07002510 count = self.getTotalFlowsNum( timeout=timeout )
Jon Halle0f0b342017-04-18 11:43:47 -07002511 count = int( count ) if count else 0
2512 return count if ( count > min ) else False
GlennRCed771242016-01-13 17:02:47 -08002513
Jon Halle0f0b342017-04-18 11:43:47 -07002514 def checkFlowsState( self, isPENDING=True, timeout=60, noExit=False ):
kelvin-onlab4df89f22015-04-13 18:10:23 -07002515 """
2516 Description:
GlennRCed771242016-01-13 17:02:47 -08002517 Check the if all the current flows are in ADDED state
Jon Hallc6793552016-01-19 14:18:37 -08002518 We check PENDING_ADD, PENDING_REMOVE, REMOVED, and FAILED flows,
2519 if the count of those states is 0, which means all current flows
2520 are in ADDED state, and return main.TRUE otherwise return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002521 Optional:
GlennRCed771242016-01-13 17:02:47 -08002522 * isPENDING: whether the PENDING_ADD is also a correct status
kelvin-onlab4df89f22015-04-13 18:10:23 -07002523 Return:
2524 returnValue - Returns main.TRUE only if all flows are in
Jon Hallc6793552016-01-19 14:18:37 -08002525 ADDED state or PENDING_ADD if the isPENDING
pingping-linbab7f8a2015-09-21 17:33:36 -07002526 parameter is set true, return main.FALSE otherwise.
kelvin-onlab4df89f22015-04-13 18:10:23 -07002527 """
2528 try:
GlennRCed771242016-01-13 17:02:47 -08002529 states = ["PENDING_ADD", "PENDING_REMOVE", "REMOVED", "FAILED"]
2530 checkedStates = []
2531 statesCount = [0, 0, 0, 0]
2532 for s in states:
Jon Hallc6793552016-01-19 14:18:37 -08002533 rawFlows = self.flows( state=s, timeout = timeout )
YPZhang240842b2016-05-17 12:00:50 -07002534 if rawFlows:
2535 # if we didn't get flows or flows function return None, we should return
2536 # main.Flase
2537 checkedStates.append( json.loads( rawFlows ) )
2538 else:
2539 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08002540 for i in range( len( states ) ):
GlennRCed771242016-01-13 17:02:47 -08002541 for c in checkedStates[i]:
Jon Hallc6793552016-01-19 14:18:37 -08002542 try:
2543 statesCount[i] += int( c.get( "flowCount" ) )
2544 except TypeError:
2545 main.log.exception( "Json object not as expected" )
2546 main.log.info( states[i] + " flows: " + str( statesCount[i] ) )
kelvin-onlabf2ec6e02015-05-27 14:15:28 -07002547
GlennRCed771242016-01-13 17:02:47 -08002548 # We want to count PENDING_ADD if isPENDING is true
2549 if isPENDING:
2550 if statesCount[1] + statesCount[2] + statesCount[3] > 0:
2551 return main.FALSE
pingping-linbab7f8a2015-09-21 17:33:36 -07002552 else:
GlennRCed771242016-01-13 17:02:47 -08002553 if statesCount[0] + statesCount[1] + statesCount[2] + statesCount[3] > 0:
2554 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08002555 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08002556 except ( TypeError, ValueError ):
2557 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawFlows ) )
kelvin-onlab4df89f22015-04-13 18:10:23 -07002558 return None
Jeremy Songster9385d412016-06-02 17:57:36 -07002559
YPZhang240842b2016-05-17 12:00:50 -07002560 except AssertionError:
2561 main.log.exception( "" )
2562 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002563 except pexpect.TIMEOUT:
2564 main.log.error( self.name + ": ONOS timeout" )
2565 return None
kelvin-onlab4df89f22015-04-13 18:10:23 -07002566 except pexpect.EOF:
2567 main.log.error( self.name + ": EOF exception found" )
2568 main.log.error( self.name + ": " + self.handle.before )
2569 main.cleanup()
2570 main.exit()
2571 except Exception:
2572 main.log.exception( self.name + ": Uncaught exception!" )
2573 main.cleanup()
2574 main.exit()
2575
GlennRCed771242016-01-13 17:02:47 -08002576 def pushTestIntents( self, ingress, egress, batchSize, offset="",
YPZhangb34b7e12016-06-14 14:28:19 -07002577 options="", timeout=10, background = False, noExit=False, getResponse=False ):
kelvin8ec71442015-01-15 16:57:00 -08002578 """
andrewonlab87852b02014-11-19 18:44:19 -05002579 Description:
Jon Halle3f39ff2015-01-13 11:50:53 -08002580 Push a number of intents in a batch format to
andrewonlab87852b02014-11-19 18:44:19 -05002581 a specific point-to-point intent definition
2582 Required:
GlennRCed771242016-01-13 17:02:47 -08002583 * ingress: specify source dpid
2584 * egress: specify destination dpid
2585 * batchSize: specify number of intents to push
andrewonlab87852b02014-11-19 18:44:19 -05002586 Optional:
GlennRCed771242016-01-13 17:02:47 -08002587 * offset: the keyOffset is where the next batch of intents
2588 will be installed
YPZhangb34b7e12016-06-14 14:28:19 -07002589 * noExit: If set to True, TestON will not exit if any error when issus command
2590 * getResponse: If set to True, function will return ONOS response.
2591
GlennRCed771242016-01-13 17:02:47 -08002592 Returns: If failed to push test intents, it will returen None,
2593 if successful, return true.
2594 Timeout expection will return None,
2595 TypeError will return false
2596 other expections will exit()
kelvin8ec71442015-01-15 16:57:00 -08002597 """
andrewonlab87852b02014-11-19 18:44:19 -05002598 try:
GlennRCed771242016-01-13 17:02:47 -08002599 if background:
2600 back = "&"
andrewonlab87852b02014-11-19 18:44:19 -05002601 else:
GlennRCed771242016-01-13 17:02:47 -08002602 back = ""
2603 cmd = "push-test-intents {} {} {} {} {} {}".format( options,
Jon Hallc6793552016-01-19 14:18:37 -08002604 ingress,
2605 egress,
2606 batchSize,
2607 offset,
2608 back )
YPZhangebf9eb52016-05-12 15:20:24 -07002609 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
You Wangb5a55f72017-03-03 12:51:05 -08002610 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002611 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08002612 main.log.info( response )
YPZhangb34b7e12016-06-14 14:28:19 -07002613 if getResponse:
2614 return response
2615
GlennRCed771242016-01-13 17:02:47 -08002616 # TODO: We should handle if there is failure in installation
2617 return main.TRUE
2618
Jon Hallc6793552016-01-19 14:18:37 -08002619 except AssertionError:
2620 main.log.exception( "" )
2621 return None
GlennRCed771242016-01-13 17:02:47 -08002622 except pexpect.TIMEOUT:
2623 main.log.error( self.name + ": ONOS timeout" )
Jon Halld4d4b372015-01-28 16:02:41 -08002624 return None
andrewonlab87852b02014-11-19 18:44:19 -05002625 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002626 main.log.error( self.name + ": EOF exception found" )
2627 main.log.error( self.name + ": " + self.handle.before )
andrewonlab87852b02014-11-19 18:44:19 -05002628 main.cleanup()
2629 main.exit()
GlennRCed771242016-01-13 17:02:47 -08002630 except TypeError:
2631 main.log.exception( self.name + ": Object not as expected" )
Jon Hallc6793552016-01-19 14:18:37 -08002632 return None
Jon Hallfebb1c72015-03-05 13:30:09 -08002633 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002634 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab87852b02014-11-19 18:44:19 -05002635 main.cleanup()
2636 main.exit()
2637
YPZhangebf9eb52016-05-12 15:20:24 -07002638 def getTotalFlowsNum( self, timeout=60, noExit=False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002639 """
2640 Description:
YPZhangf6f14a02016-01-28 15:17:31 -08002641 Get the number of ADDED flows.
YPZhangb5d3f832016-01-23 22:54:26 -08002642 Return:
YPZhangf6f14a02016-01-28 15:17:31 -08002643 The number of ADDED flows
YPZhang14a4aa92016-07-15 13:37:15 -07002644 Or return None if any exceptions
YPZhangb5d3f832016-01-23 22:54:26 -08002645 """
YPZhange3109a72016-02-02 11:25:37 -08002646
YPZhangb5d3f832016-01-23 22:54:26 -08002647 try:
YPZhange3109a72016-02-02 11:25:37 -08002648 # get total added flows number
YPZhang14a4aa92016-07-15 13:37:15 -07002649 cmd = "flows -c added"
2650 rawFlows = self.sendline( cmd, timeout=timeout, noExit=noExit )
2651 if rawFlows:
2652 rawFlows = rawFlows.split("\n")
YPZhange3109a72016-02-02 11:25:37 -08002653 totalFlows = 0
YPZhang14a4aa92016-07-15 13:37:15 -07002654 for l in rawFlows:
2655 totalFlows += int(l.split("Count=")[1])
2656 else:
2657 main.log.error("Response not as expected!")
2658 return None
2659 return totalFlows
YPZhange3109a72016-02-02 11:25:37 -08002660
You Wangd3cb2ce2016-05-16 14:01:24 -07002661 except ( TypeError, ValueError ):
YPZhang14a4aa92016-07-15 13:37:15 -07002662 main.log.exception( "{}: Object not as expected!".format( self.name ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002663 return None
2664 except pexpect.EOF:
2665 main.log.error( self.name + ": EOF exception found" )
2666 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002667 if not noExit:
2668 main.cleanup()
2669 main.exit()
2670 return None
Jon Halle0f0b342017-04-18 11:43:47 -07002671 except pexpect.TIMEOUT:
2672 main.log.error( self.name + ": ONOS timeout" )
2673 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002674 except Exception:
2675 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002676 if not noExit:
2677 main.cleanup()
2678 main.exit()
2679 return None
YPZhangb5d3f832016-01-23 22:54:26 -08002680
YPZhang14a4aa92016-07-15 13:37:15 -07002681 def getTotalIntentsNum( self, timeout=60, noExit = False ):
YPZhangb5d3f832016-01-23 22:54:26 -08002682 """
2683 Description:
2684 Get the total number of intents, include every states.
YPZhang14a4aa92016-07-15 13:37:15 -07002685 Optional:
2686 noExit - If noExit, TestON will not exit if any except.
YPZhangb5d3f832016-01-23 22:54:26 -08002687 Return:
2688 The number of intents
2689 """
2690 try:
2691 cmd = "summary -j"
YPZhang14a4aa92016-07-15 13:37:15 -07002692 response = self.sendline( cmd, timeout=timeout, noExit=noExit )
Jon Halle0f0b342017-04-18 11:43:47 -07002693 if response is None:
2694 return -1
YPZhangb5d3f832016-01-23 22:54:26 -08002695 response = json.loads( response )
2696 return int( response.get("intents") )
You Wangd3cb2ce2016-05-16 14:01:24 -07002697 except ( TypeError, ValueError ):
2698 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, response ) )
YPZhangb5d3f832016-01-23 22:54:26 -08002699 return None
2700 except pexpect.EOF:
2701 main.log.error( self.name + ": EOF exception found" )
2702 main.log.error( self.name + ": " + self.handle.before )
YPZhang14a4aa92016-07-15 13:37:15 -07002703 if noExit:
2704 return -1
2705 else:
2706 main.cleanup()
2707 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002708 except Exception:
2709 main.log.exception( self.name + ": Uncaught exception!" )
YPZhang14a4aa92016-07-15 13:37:15 -07002710 if noExit:
2711 return -1
2712 else:
2713 main.cleanup()
2714 main.exit()
YPZhangb5d3f832016-01-23 22:54:26 -08002715
kelvin-onlabd3b64892015-01-20 13:26:24 -08002716 def intentsEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002717 """
Jon Halle3f39ff2015-01-13 11:50:53 -08002718 Description:Returns topology metrics
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002719 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002720 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002721 """
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002722 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002723 cmdStr = "intents-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002724 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002725 cmdStr += " -j"
2726 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002727 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002728 assert "Command not found:" not in handle, handle
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002729 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002730 except AssertionError:
2731 main.log.exception( "" )
2732 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002733 except TypeError:
2734 main.log.exception( self.name + ": Object not as expected" )
2735 return None
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002736 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002737 main.log.error( self.name + ": EOF exception found" )
2738 main.log.error( self.name + ": " + self.handle.before )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002739 main.cleanup()
2740 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002741 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002742 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab0dbb6ec2014-11-06 13:46:55 -05002743 main.cleanup()
2744 main.exit()
Shreya Shah0f01c812014-10-26 20:15:28 -04002745
kelvin-onlabd3b64892015-01-20 13:26:24 -08002746 def topologyEventsMetrics( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08002747 """
2748 Description:Returns topology metrics
andrewonlab867212a2014-10-22 20:13:38 -04002749 Optional:
kelvin-onlabd3b64892015-01-20 13:26:24 -08002750 * jsonFormat: enable json formatting of output
kelvin8ec71442015-01-15 16:57:00 -08002751 """
andrewonlab867212a2014-10-22 20:13:38 -04002752 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07002753 cmdStr = "topology-events-metrics"
kelvin-onlabd3b64892015-01-20 13:26:24 -08002754 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07002755 cmdStr += " -j"
2756 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002757 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002758 assert "Command not found:" not in handle, handle
jenkins7ead5a82015-03-13 10:28:21 -07002759 if handle:
2760 return handle
Jon Hallc6358dd2015-04-10 12:44:28 -07002761 elif jsonFormat:
Jon Hallbe379602015-03-24 13:39:32 -07002762 # Return empty json
jenkins7ead5a82015-03-13 10:28:21 -07002763 return '{}'
Jon Hallc6358dd2015-04-10 12:44:28 -07002764 else:
2765 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002766 except AssertionError:
2767 main.log.exception( "" )
2768 return None
Jon Halld4d4b372015-01-28 16:02:41 -08002769 except TypeError:
2770 main.log.exception( self.name + ": Object not as expected" )
2771 return None
andrewonlab867212a2014-10-22 20:13:38 -04002772 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002773 main.log.error( self.name + ": EOF exception found" )
2774 main.log.error( self.name + ": " + self.handle.before )
andrewonlab867212a2014-10-22 20:13:38 -04002775 main.cleanup()
2776 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002777 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002778 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab867212a2014-10-22 20:13:38 -04002779 main.cleanup()
2780 main.exit()
2781
kelvin8ec71442015-01-15 16:57:00 -08002782 # Wrapper functions ****************
2783 # Wrapper functions use existing driver
2784 # functions and extends their use case.
2785 # For example, we may use the output of
2786 # a normal driver function, and parse it
2787 # using a wrapper function
andrewonlabc2d05aa2014-10-13 16:51:10 -04002788
kelvin-onlabd3b64892015-01-20 13:26:24 -08002789 def getAllIntentsId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002790 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002791 Description:
2792 Obtain all intent id's in a list
kelvin8ec71442015-01-15 16:57:00 -08002793 """
andrewonlab9a50dfe2014-10-17 17:22:31 -04002794 try:
kelvin8ec71442015-01-15 16:57:00 -08002795 # Obtain output of intents function
Jon Hall6021e062017-01-30 11:10:06 -08002796 intentsStr = self.intents(jsonFormat=True)
Jon Hall7a6ebfd2017-03-13 10:58:58 -07002797 if intentsStr is None:
2798 raise TypeError
Jon Hall6021e062017-01-30 11:10:06 -08002799 # Convert to a dictionary
2800 intents = json.loads( intentsStr )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002801 intentIdList = []
Jon Hall6021e062017-01-30 11:10:06 -08002802 for intent in intents:
2803 intentIdList.append( intent[ 'id' ] )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002804 return intentIdList
Jon Halld4d4b372015-01-28 16:02:41 -08002805 except TypeError:
2806 main.log.exception( self.name + ": Object not as expected" )
2807 return None
andrewonlab9a50dfe2014-10-17 17:22:31 -04002808 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002809 main.log.error( self.name + ": EOF exception found" )
2810 main.log.error( self.name + ": " + self.handle.before )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002811 main.cleanup()
2812 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002813 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002814 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab9a50dfe2014-10-17 17:22:31 -04002815 main.cleanup()
2816 main.exit()
2817
You Wang3c276252016-09-21 15:21:36 -07002818 def flowAddedCount( self, deviceId, core=False ):
Jon Hall30b82fa2015-03-04 17:15:43 -08002819 """
2820 Determine the number of flow rules for the given device id that are
2821 in the added state
You Wang3c276252016-09-21 15:21:36 -07002822 Params:
2823 core: if True, only return the number of core flows added
Jon Hall30b82fa2015-03-04 17:15:43 -08002824 """
2825 try:
You Wang3c276252016-09-21 15:21:36 -07002826 if core:
2827 cmdStr = "flows any " + str( deviceId ) + " | " +\
2828 "grep 'state=ADDED' | grep org.onosproject.core | wc -l"
2829 else:
2830 cmdStr = "flows any " + str( deviceId ) + " | " +\
2831 "grep 'state=ADDED' | wc -l"
Jon Hall30b82fa2015-03-04 17:15:43 -08002832 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08002833 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08002834 assert "Command not found:" not in handle, handle
Jon Hall30b82fa2015-03-04 17:15:43 -08002835 return handle
Jon Hallc6793552016-01-19 14:18:37 -08002836 except AssertionError:
2837 main.log.exception( "" )
2838 return None
Jon Hall30b82fa2015-03-04 17:15:43 -08002839 except pexpect.EOF:
2840 main.log.error( self.name + ": EOF exception found" )
2841 main.log.error( self.name + ": " + self.handle.before )
2842 main.cleanup()
2843 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002844 except Exception:
Jon Hall30b82fa2015-03-04 17:15:43 -08002845 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab95ce8322014-10-13 14:12:04 -04002846 main.cleanup()
2847 main.exit()
2848
kelvin-onlabd3b64892015-01-20 13:26:24 -08002849 def getAllDevicesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002850 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002851 Use 'devices' function to obtain list of all devices
2852 and parse the result to obtain a list of all device
2853 id's. Returns this list. Returns empty list if no
2854 devices exist
kelvin8ec71442015-01-15 16:57:00 -08002855 List is ordered sequentially
2856
andrewonlab3e15ead2014-10-15 14:21:34 -04002857 This function may be useful if you are not sure of the
kelvin8ec71442015-01-15 16:57:00 -08002858 device id, and wish to execute other commands using
andrewonlab3e15ead2014-10-15 14:21:34 -04002859 the ids. By obtaining the list of device ids on the fly,
2860 you can iterate through the list to get mastership, etc.
kelvin8ec71442015-01-15 16:57:00 -08002861 """
andrewonlab7e4d2d32014-10-15 13:23:21 -04002862 try:
kelvin8ec71442015-01-15 16:57:00 -08002863 # Call devices and store result string
kelvin-onlabd3b64892015-01-20 13:26:24 -08002864 devicesStr = self.devices( jsonFormat=False )
2865 idList = []
kelvin8ec71442015-01-15 16:57:00 -08002866
kelvin-onlabd3b64892015-01-20 13:26:24 -08002867 if not devicesStr:
kelvin8ec71442015-01-15 16:57:00 -08002868 main.log.info( "There are no devices to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002869 return idList
kelvin8ec71442015-01-15 16:57:00 -08002870
2871 # Split the string into list by comma
kelvin-onlabd3b64892015-01-20 13:26:24 -08002872 deviceList = devicesStr.split( "," )
kelvin8ec71442015-01-15 16:57:00 -08002873 # Get temporary list of all arguments with string 'id='
kelvin-onlabd3b64892015-01-20 13:26:24 -08002874 tempList = [ dev for dev in deviceList if "id=" in dev ]
kelvin8ec71442015-01-15 16:57:00 -08002875 # Split list further into arguments before and after string
2876 # 'id='. Get the latter portion ( the actual device id ) and
kelvin-onlabd3b64892015-01-20 13:26:24 -08002877 # append to idList
2878 for arg in tempList:
2879 idList.append( arg.split( "id=" )[ 1 ] )
2880 return idList
andrewonlab7e4d2d32014-10-15 13:23:21 -04002881
Jon Halld4d4b372015-01-28 16:02:41 -08002882 except TypeError:
2883 main.log.exception( self.name + ": Object not as expected" )
2884 return None
andrewonlab7e4d2d32014-10-15 13:23:21 -04002885 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002886 main.log.error( self.name + ": EOF exception found" )
2887 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002888 main.cleanup()
2889 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002890 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002891 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7e4d2d32014-10-15 13:23:21 -04002892 main.cleanup()
2893 main.exit()
2894
kelvin-onlabd3b64892015-01-20 13:26:24 -08002895 def getAllNodesId( self ):
kelvin8ec71442015-01-15 16:57:00 -08002896 """
andrewonlab7c211572014-10-15 16:45:20 -04002897 Uses 'nodes' function to obtain list of all nodes
2898 and parse the result of nodes to obtain just the
kelvin8ec71442015-01-15 16:57:00 -08002899 node id's.
andrewonlab7c211572014-10-15 16:45:20 -04002900 Returns:
2901 list of node id's
kelvin8ec71442015-01-15 16:57:00 -08002902 """
andrewonlab7c211572014-10-15 16:45:20 -04002903 try:
Jon Hall5aa168b2015-03-23 14:23:09 -07002904 nodesStr = self.nodes( jsonFormat=True )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002905 idList = []
Jon Hall5aa168b2015-03-23 14:23:09 -07002906 # Sample nodesStr output
Jon Hallbd182782016-03-28 16:42:22 -07002907 # id=local, address=127.0.0.1:9876, state=READY *
kelvin-onlabd3b64892015-01-20 13:26:24 -08002908 if not nodesStr:
kelvin8ec71442015-01-15 16:57:00 -08002909 main.log.info( "There are no nodes to get id from" )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002910 return idList
Jon Hall5aa168b2015-03-23 14:23:09 -07002911 nodesJson = json.loads( nodesStr )
2912 idList = [ node.get('id') for node in nodesJson ]
kelvin-onlabd3b64892015-01-20 13:26:24 -08002913 return idList
Jon Hallc6793552016-01-19 14:18:37 -08002914 except ( TypeError, ValueError ):
2915 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, nodesStr ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002916 return None
andrewonlab7c211572014-10-15 16:45:20 -04002917 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002918 main.log.error( self.name + ": EOF exception found" )
2919 main.log.error( self.name + ": " + self.handle.before )
andrewonlab7c211572014-10-15 16:45:20 -04002920 main.cleanup()
2921 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002922 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002923 main.log.exception( self.name + ": Uncaught exception!" )
andrewonlab7c211572014-10-15 16:45:20 -04002924 main.cleanup()
2925 main.exit()
andrewonlab7e4d2d32014-10-15 13:23:21 -04002926
kelvin-onlabd3b64892015-01-20 13:26:24 -08002927 def getDevice( self, dpid=None ):
kelvin8ec71442015-01-15 16:57:00 -08002928 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002929 Return the first device from the devices api whose 'id' contains 'dpid'
2930 Return None if there is no match
kelvin8ec71442015-01-15 16:57:00 -08002931 """
Jon Halla91c4dc2014-10-22 12:57:04 -04002932 try:
kelvin8ec71442015-01-15 16:57:00 -08002933 if dpid is None:
Jon Halla91c4dc2014-10-22 12:57:04 -04002934 return None
2935 else:
kelvin8ec71442015-01-15 16:57:00 -08002936 dpid = dpid.replace( ':', '' )
kelvin-onlabd3b64892015-01-20 13:26:24 -08002937 rawDevices = self.devices()
2938 devicesJson = json.loads( rawDevices )
kelvin8ec71442015-01-15 16:57:00 -08002939 # search json for the device with dpid then return the device
kelvin-onlabd3b64892015-01-20 13:26:24 -08002940 for device in devicesJson:
kelvin8ec71442015-01-15 16:57:00 -08002941 # print "%s in %s?" % ( dpid, device[ 'id' ] )
2942 if dpid in device[ 'id' ]:
Jon Halla91c4dc2014-10-22 12:57:04 -04002943 return device
2944 return None
Jon Hallc6793552016-01-19 14:18:37 -08002945 except ( TypeError, ValueError ):
2946 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawDevices ) )
Jon Halld4d4b372015-01-28 16:02:41 -08002947 return None
Jon Halla91c4dc2014-10-22 12:57:04 -04002948 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08002949 main.log.error( self.name + ": EOF exception found" )
2950 main.log.error( self.name + ": " + self.handle.before )
Jon Halla91c4dc2014-10-22 12:57:04 -04002951 main.cleanup()
2952 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08002953 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08002954 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halla91c4dc2014-10-22 12:57:04 -04002955 main.cleanup()
2956 main.exit()
2957
You Wang24139872016-05-03 11:48:47 -07002958 def getTopology( self, topologyOutput ):
2959 """
2960 Definition:
2961 Loads a json topology output
2962 Return:
2963 topology = current ONOS topology
2964 """
2965 import json
2966 try:
2967 # either onos:topology or 'topology' will work in CLI
2968 topology = json.loads(topologyOutput)
Jeremy Songsterbc2d8ac2016-05-04 11:25:42 -07002969 main.log.debug( topology )
You Wang24139872016-05-03 11:48:47 -07002970 return topology
You Wangd3cb2ce2016-05-16 14:01:24 -07002971 except ( TypeError, ValueError ):
2972 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, topologyOutput ) )
2973 return None
You Wang24139872016-05-03 11:48:47 -07002974 except pexpect.EOF:
2975 main.log.error( self.name + ": EOF exception found" )
2976 main.log.error( self.name + ": " + self.handle.before )
2977 main.cleanup()
2978 main.exit()
2979 except Exception:
2980 main.log.exception( self.name + ": Uncaught exception!" )
2981 main.cleanup()
2982 main.exit()
2983
Flavio Castro82ee2f62016-06-07 15:04:12 -07002984 def checkStatus(self, numoswitch, numolink, numoctrl = -1, logLevel="info"):
kelvin8ec71442015-01-15 16:57:00 -08002985 """
Jon Hallefbd9792015-03-05 16:11:36 -08002986 Checks the number of switches & links that ONOS sees against the
kelvin8ec71442015-01-15 16:57:00 -08002987 supplied values. By default this will report to main.log, but the
You Wang24139872016-05-03 11:48:47 -07002988 log level can be specific.
kelvin8ec71442015-01-15 16:57:00 -08002989
Flavio Castro82ee2f62016-06-07 15:04:12 -07002990 Params: numoswitch = expected number of switches
Jon Hallefbd9792015-03-05 16:11:36 -08002991 numolink = expected number of links
Flavio Castro82ee2f62016-06-07 15:04:12 -07002992 numoctrl = expected number of controllers
You Wang24139872016-05-03 11:48:47 -07002993 logLevel = level to log to.
2994 Currently accepts 'info', 'warn' and 'report'
Jon Hall42db6dc2014-10-24 19:03:48 -04002995
Jon Hallefbd9792015-03-05 16:11:36 -08002996 Returns: main.TRUE if the number of switches and links are correct,
2997 main.FALSE if the number of switches and links is incorrect,
Jon Hall42db6dc2014-10-24 19:03:48 -04002998 and main.ERROR otherwise
kelvin8ec71442015-01-15 16:57:00 -08002999 """
Flavio Castro82ee2f62016-06-07 15:04:12 -07003000 import json
Jon Hall42db6dc2014-10-24 19:03:48 -04003001 try:
You Wang13310252016-07-31 10:56:14 -07003002 summary = self.summary()
3003 summary = json.loads( summary )
Flavio Castrof5b3f872016-06-23 17:52:31 -07003004 except ( TypeError, ValueError ):
3005 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, summary ) )
3006 return main.ERROR
3007 try:
3008 topology = self.getTopology( self.topology() )
Jon Halle0f0b342017-04-18 11:43:47 -07003009 if topology == {} or topology is None or summary == {} or summary is None:
Jon Hall42db6dc2014-10-24 19:03:48 -04003010 return main.ERROR
3011 output = ""
kelvin8ec71442015-01-15 16:57:00 -08003012 # Is the number of switches is what we expected
3013 devices = topology.get( 'devices', False )
3014 links = topology.get( 'links', False )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003015 nodes = summary.get( 'nodes', False )
3016 if devices is False or links is False or nodes is False:
Jon Hall42db6dc2014-10-24 19:03:48 -04003017 return main.ERROR
kelvin-onlabd3b64892015-01-20 13:26:24 -08003018 switchCheck = ( int( devices ) == int( numoswitch ) )
kelvin8ec71442015-01-15 16:57:00 -08003019 # Is the number of links is what we expected
kelvin-onlabd3b64892015-01-20 13:26:24 -08003020 linkCheck = ( int( links ) == int( numolink ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07003021 nodeCheck = ( int( nodes ) == int( numoctrl ) ) or int( numoctrl ) == -1
3022 if switchCheck and linkCheck and nodeCheck:
kelvin8ec71442015-01-15 16:57:00 -08003023 # We expected the correct numbers
You Wang24139872016-05-03 11:48:47 -07003024 output = output + "The number of links and switches match "\
3025 + "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003026 result = main.TRUE
3027 else:
You Wang24139872016-05-03 11:48:47 -07003028 output = output + \
3029 "The number of links and switches does not match " + \
3030 "what was expected"
Jon Hall42db6dc2014-10-24 19:03:48 -04003031 result = main.FALSE
You Wang24139872016-05-03 11:48:47 -07003032 output = output + "\n ONOS sees %i devices" % int( devices )
3033 output = output + " (%i expected) " % int( numoswitch )
3034 output = output + "and %i links " % int( links )
3035 output = output + "(%i expected)" % int( numolink )
YPZhangd7e4b6e2016-06-17 16:07:55 -07003036 if int( numoctrl ) > 0:
Flavio Castro82ee2f62016-06-07 15:04:12 -07003037 output = output + "and %i controllers " % int( nodes )
3038 output = output + "(%i expected)" % int( numoctrl )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003039 if logLevel == "report":
kelvin8ec71442015-01-15 16:57:00 -08003040 main.log.report( output )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003041 elif logLevel == "warn":
kelvin8ec71442015-01-15 16:57:00 -08003042 main.log.warn( output )
Jon Hall42db6dc2014-10-24 19:03:48 -04003043 else:
You Wang24139872016-05-03 11:48:47 -07003044 main.log.info( output )
kelvin8ec71442015-01-15 16:57:00 -08003045 return result
Jon Hall42db6dc2014-10-24 19:03:48 -04003046 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003047 main.log.error( self.name + ": EOF exception found" )
3048 main.log.error( self.name + ": " + self.handle.before )
Jon Hall42db6dc2014-10-24 19:03:48 -04003049 main.cleanup()
3050 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003051 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003052 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall42db6dc2014-10-24 19:03:48 -04003053 main.cleanup()
3054 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003055
kelvin-onlabd3b64892015-01-20 13:26:24 -08003056 def deviceRole( self, deviceId, onosNode, role="master" ):
kelvin8ec71442015-01-15 16:57:00 -08003057 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003058 Calls the device-role cli command.
kelvin-onlabd3b64892015-01-20 13:26:24 -08003059 deviceId must be the id of a device as seen in the onos devices command
3060 onosNode is the ip of one of the onos nodes in the cluster
Jon Hall1c9e8732014-10-27 19:29:27 -04003061 role must be either master, standby, or none
3062
Jon Halle3f39ff2015-01-13 11:50:53 -08003063 Returns:
3064 main.TRUE or main.FALSE based on argument verification and
3065 main.ERROR if command returns and error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003066 """
Jon Hall1c9e8732014-10-27 19:29:27 -04003067 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003068 if role.lower() == "master" or role.lower() == "standby" or\
Jon Hall1c9e8732014-10-27 19:29:27 -04003069 role.lower() == "none":
kelvin-onlabd3b64892015-01-20 13:26:24 -08003070 cmdStr = "device-role " +\
3071 str( deviceId ) + " " +\
3072 str( onosNode ) + " " +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003073 str( role )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003074 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003075 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003076 assert "Command not found:" not in handle, handle
kelvin-onlab898a6c62015-01-16 14:13:53 -08003077 if re.search( "Error", handle ):
3078 # end color output to escape any colours
3079 # from the cli
kelvin8ec71442015-01-15 16:57:00 -08003080 main.log.error( self.name + ": " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003081 handle + '\033[0m' )
kelvin8ec71442015-01-15 16:57:00 -08003082 return main.ERROR
kelvin8ec71442015-01-15 16:57:00 -08003083 return main.TRUE
Jon Hall1c9e8732014-10-27 19:29:27 -04003084 else:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003085 main.log.error( "Invalid 'role' given to device_role(). " +
3086 "Value was '" + str(role) + "'." )
Jon Hall1c9e8732014-10-27 19:29:27 -04003087 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003088 except AssertionError:
3089 main.log.exception( "" )
3090 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003091 except TypeError:
3092 main.log.exception( self.name + ": Object not as expected" )
3093 return None
Jon Hall1c9e8732014-10-27 19:29:27 -04003094 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003095 main.log.error( self.name + ": EOF exception found" )
3096 main.log.error( self.name + ": " + self.handle.before )
Jon Hall1c9e8732014-10-27 19:29:27 -04003097 main.cleanup()
3098 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003099 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003100 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall1c9e8732014-10-27 19:29:27 -04003101 main.cleanup()
3102 main.exit()
3103
kelvin-onlabd3b64892015-01-20 13:26:24 -08003104 def clusters( self, jsonFormat=True ):
kelvin8ec71442015-01-15 16:57:00 -08003105 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003106 Lists all clusters
Jon Hallffb386d2014-11-21 13:43:38 -08003107 Optional argument:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003108 * jsonFormat - boolean indicating if you want output in json
kelvin8ec71442015-01-15 16:57:00 -08003109 """
Jon Hall73cf9cc2014-11-20 22:28:38 -08003110 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003111 cmdStr = "clusters"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003112 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003113 cmdStr += " -j"
3114 handle = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003115 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003116 assert "Command not found:" not in handle, handle
Jon Hallc6358dd2015-04-10 12:44:28 -07003117 return handle
Jon Hallc6793552016-01-19 14:18:37 -08003118 except AssertionError:
3119 main.log.exception( "" )
3120 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003121 except TypeError:
3122 main.log.exception( self.name + ": Object not as expected" )
3123 return None
Jon Hall73cf9cc2014-11-20 22:28:38 -08003124 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003125 main.log.error( self.name + ": EOF exception found" )
3126 main.log.error( self.name + ": " + self.handle.before )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003127 main.cleanup()
3128 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003129 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003130 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall73cf9cc2014-11-20 22:28:38 -08003131 main.cleanup()
3132 main.exit()
3133
kelvin-onlabd3b64892015-01-20 13:26:24 -08003134 def electionTestLeader( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003135 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003136 CLI command to get the current leader for the Election test application
3137 NOTE: Requires installation of the onos-app-election feature
3138 Returns: Node IP of the leader if one exists
3139 None if none exists
3140 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003141 """
Jon Hall94fd0472014-12-08 11:52:42 -08003142 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003143 cmdStr = "election-test-leader"
3144 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003145 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003146 assert "Command not found:" not in response, response
Jon Halle3f39ff2015-01-13 11:50:53 -08003147 # Leader
3148 leaderPattern = "The\scurrent\sleader\sfor\sthe\sElection\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003149 "app\sis\s(?P<node>.+)\."
kelvin-onlabd3b64892015-01-20 13:26:24 -08003150 nodeSearch = re.search( leaderPattern, response )
3151 if nodeSearch:
3152 node = nodeSearch.group( 'node' )
Jon Halle3f39ff2015-01-13 11:50:53 -08003153 main.log.info( "Election-test-leader on " + str( self.name ) +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003154 " found " + node + " as the leader" )
Jon Hall94fd0472014-12-08 11:52:42 -08003155 return node
Jon Halle3f39ff2015-01-13 11:50:53 -08003156 # no leader
3157 nullPattern = "There\sis\scurrently\sno\sleader\selected\sfor\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003158 "the\sElection\sapp"
kelvin-onlabd3b64892015-01-20 13:26:24 -08003159 nullSearch = re.search( nullPattern, response )
3160 if nullSearch:
Jon Halle3f39ff2015-01-13 11:50:53 -08003161 main.log.info( "Election-test-leader found no leader on " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003162 self.name )
Jon Hall94fd0472014-12-08 11:52:42 -08003163 return None
kelvin-onlab898a6c62015-01-16 14:13:53 -08003164 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003165 main.log.error( "Error in electionTestLeader on " + self.name +
3166 ": " + "unexpected response" )
3167 main.log.error( repr( response ) )
3168 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003169 except AssertionError:
3170 main.log.exception( "" )
3171 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003172 except TypeError:
3173 main.log.exception( self.name + ": Object not as expected" )
3174 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003175 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003176 main.log.error( self.name + ": EOF exception found" )
3177 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003178 main.cleanup()
3179 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003180 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003181 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003182 main.cleanup()
3183 main.exit()
3184
kelvin-onlabd3b64892015-01-20 13:26:24 -08003185 def electionTestRun( self ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003186 """
Jon Halle3f39ff2015-01-13 11:50:53 -08003187 CLI command to run for leadership of the Election test application.
3188 NOTE: Requires installation of the onos-app-election feature
3189 Returns: Main.TRUE on success
3190 Main.FALSE on error
kelvin-onlab898a6c62015-01-16 14:13:53 -08003191 """
Jon Hall94fd0472014-12-08 11:52:42 -08003192 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003193 cmdStr = "election-test-run"
3194 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003195 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003196 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003197 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003198 successPattern = "Entering\sleadership\selections\sfor\sthe\s" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003199 "Election\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003200 search = re.search( successPattern, response )
Jon Hall94fd0472014-12-08 11:52:42 -08003201 if search:
Jon Halle3f39ff2015-01-13 11:50:53 -08003202 main.log.info( self.name + " entering leadership elections " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003203 "for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003204 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003205 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003206 main.log.error( "Error in electionTestRun on " + self.name +
3207 ": " + "unexpected response" )
3208 main.log.error( repr( response ) )
3209 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003210 except AssertionError:
3211 main.log.exception( "" )
3212 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003213 except TypeError:
3214 main.log.exception( self.name + ": Object not as expected" )
3215 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003216 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003217 main.log.error( self.name + ": EOF exception found" )
3218 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003219 main.cleanup()
3220 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003221 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003222 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003223 main.cleanup()
3224 main.exit()
3225
kelvin-onlabd3b64892015-01-20 13:26:24 -08003226 def electionTestWithdraw( self ):
kelvin8ec71442015-01-15 16:57:00 -08003227 """
Jon Hall94fd0472014-12-08 11:52:42 -08003228 * CLI command to withdraw the local node from leadership election for
3229 * the Election test application.
3230 #NOTE: Requires installation of the onos-app-election feature
3231 Returns: Main.TRUE on success
3232 Main.FALSE on error
kelvin8ec71442015-01-15 16:57:00 -08003233 """
Jon Hall94fd0472014-12-08 11:52:42 -08003234 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003235 cmdStr = "election-test-withdraw"
3236 response = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003237 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003238 assert "Command not found:" not in response, response
kelvin-onlab898a6c62015-01-16 14:13:53 -08003239 # success
Jon Halle3f39ff2015-01-13 11:50:53 -08003240 successPattern = "Withdrawing\sfrom\sleadership\selections\sfor" +\
kelvin-onlab898a6c62015-01-16 14:13:53 -08003241 "\sthe\sElection\sapp."
Jon Halle3f39ff2015-01-13 11:50:53 -08003242 if re.search( successPattern, response ):
3243 main.log.info( self.name + " withdrawing from leadership " +
kelvin-onlab898a6c62015-01-16 14:13:53 -08003244 "elections for the Election app." )
Jon Hall94fd0472014-12-08 11:52:42 -08003245 return main.TRUE
kelvin-onlab898a6c62015-01-16 14:13:53 -08003246 # error
Jon Hall97cf84a2016-06-20 13:35:58 -07003247 main.log.error( "Error in electionTestWithdraw on " +
3248 self.name + ": " + "unexpected response" )
3249 main.log.error( repr( response ) )
3250 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08003251 except AssertionError:
3252 main.log.exception( "" )
3253 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003254 except TypeError:
3255 main.log.exception( self.name + ": Object not as expected" )
3256 return main.FALSE
Jon Hall94fd0472014-12-08 11:52:42 -08003257 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003258 main.log.error( self.name + ": EOF exception found" )
3259 main.log.error( self.name + ": " + self.handle.before )
Jon Hall94fd0472014-12-08 11:52:42 -08003260 main.cleanup()
3261 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003262 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003263 main.log.exception( self.name + ": Uncaught exception!" )
Jon Hall94fd0472014-12-08 11:52:42 -08003264 main.cleanup()
3265 main.exit()
Jon Hall1c9e8732014-10-27 19:29:27 -04003266
kelvin8ec71442015-01-15 16:57:00 -08003267 def getDevicePortsEnabledCount( self, dpid ):
3268 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003269 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003270 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003271 try:
Jon Halle3f39ff2015-01-13 11:50:53 -08003272 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003273 cmdStr = "onos:ports -e " + dpid + " | wc -l"
3274 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003275 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003276 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003277 if re.search( "No such device", output ):
3278 main.log.error( "Error in getting ports" )
3279 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003280 return output
Jon Hallc6793552016-01-19 14:18:37 -08003281 except AssertionError:
3282 main.log.exception( "" )
3283 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003284 except TypeError:
3285 main.log.exception( self.name + ": Object not as expected" )
3286 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003287 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003288 main.log.error( self.name + ": EOF exception found" )
3289 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003290 main.cleanup()
3291 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003292 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003293 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003294 main.cleanup()
3295 main.exit()
3296
kelvin8ec71442015-01-15 16:57:00 -08003297 def getDeviceLinksActiveCount( self, dpid ):
3298 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003299 Get the count of all enabled ports on a particular device/switch
kelvin8ec71442015-01-15 16:57:00 -08003300 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003301 try:
kelvin-onlab898a6c62015-01-16 14:13:53 -08003302 dpid = str( dpid )
kelvin-onlabd3b64892015-01-20 13:26:24 -08003303 cmdStr = "onos:links " + dpid + " | grep ACTIVE | wc -l"
3304 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003305 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003306 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003307 if re.search( "No such device", output ):
kelvin-onlab898a6c62015-01-16 14:13:53 -08003308 main.log.error( "Error in getting ports " )
3309 return ( output, "Error " )
Jon Halla495f562016-05-16 18:03:26 -07003310 return output
Jon Hallc6793552016-01-19 14:18:37 -08003311 except AssertionError:
3312 main.log.exception( "" )
3313 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003314 except TypeError:
3315 main.log.exception( self.name + ": Object not as expected" )
3316 return ( output, "Error " )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003317 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003318 main.log.error( self.name + ": EOF exception found" )
3319 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003320 main.cleanup()
3321 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003322 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003323 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003324 main.cleanup()
3325 main.exit()
3326
kelvin8ec71442015-01-15 16:57:00 -08003327 def getAllIntentIds( self ):
3328 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003329 Return a list of all Intent IDs
kelvin8ec71442015-01-15 16:57:00 -08003330 """
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003331 try:
kelvin-onlabd3b64892015-01-20 13:26:24 -08003332 cmdStr = "onos:intents | grep id="
3333 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003334 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003335 assert "Command not found:" not in output, output
Jon Halle3f39ff2015-01-13 11:50:53 -08003336 if re.search( "Error", output ):
3337 main.log.error( "Error in getting ports" )
3338 return ( output, "Error" )
Jon Halla495f562016-05-16 18:03:26 -07003339 return output
Jon Hallc6793552016-01-19 14:18:37 -08003340 except AssertionError:
3341 main.log.exception( "" )
3342 return None
Jon Halld4d4b372015-01-28 16:02:41 -08003343 except TypeError:
3344 main.log.exception( self.name + ": Object not as expected" )
3345 return ( output, "Error" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003346 except pexpect.EOF:
kelvin8ec71442015-01-15 16:57:00 -08003347 main.log.error( self.name + ": EOF exception found" )
3348 main.log.error( self.name + ": " + self.handle.before )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003349 main.cleanup()
3350 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003351 except Exception:
Jon Halld4d4b372015-01-28 16:02:41 -08003352 main.log.exception( self.name + ": Uncaught exception!" )
3353 main.cleanup()
3354 main.exit()
3355
Jon Hall73509952015-02-24 16:42:56 -08003356 def intentSummary( self ):
3357 """
Jon Hallefbd9792015-03-05 16:11:36 -08003358 Returns a dictionary containing the current intent states and the count
Jon Hall73509952015-02-24 16:42:56 -08003359 """
3360 try:
3361 intents = self.intents( )
Jon Hall08f61bc2015-04-13 16:00:30 -07003362 states = []
Jon Hall5aa168b2015-03-23 14:23:09 -07003363 for intent in json.loads( intents ):
Jon Hall08f61bc2015-04-13 16:00:30 -07003364 states.append( intent.get( 'state', None ) )
3365 out = [ ( i, states.count( i ) ) for i in set( states ) ]
Jon Hall63604932015-02-26 17:09:50 -08003366 main.log.info( dict( out ) )
Jon Hall73509952015-02-24 16:42:56 -08003367 return dict( out )
Jon Hallc6793552016-01-19 14:18:37 -08003368 except ( TypeError, ValueError ):
3369 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, intents ) )
Jon Hall73509952015-02-24 16:42:56 -08003370 return None
3371 except pexpect.EOF:
3372 main.log.error( self.name + ": EOF exception found" )
3373 main.log.error( self.name + ": " + self.handle.before )
3374 main.cleanup()
3375 main.exit()
Jon Hallfebb1c72015-03-05 13:30:09 -08003376 except Exception:
Jon Hall73509952015-02-24 16:42:56 -08003377 main.log.exception( self.name + ": Uncaught exception!" )
3378 main.cleanup()
3379 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003380
Jon Hall61282e32015-03-19 11:34:11 -07003381 def leaders( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003382 """
3383 Returns the output of the leaders command.
Jon Hall61282e32015-03-19 11:34:11 -07003384 Optional argument:
3385 * jsonFormat - boolean indicating if you want output in json
Jon Hall63604932015-02-26 17:09:50 -08003386 """
Jon Hall63604932015-02-26 17:09:50 -08003387 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003388 cmdStr = "onos:leaders"
Jon Hall61282e32015-03-19 11:34:11 -07003389 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003390 cmdStr += " -j"
3391 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003392 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003393 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003394 return output
Jon Hallc6793552016-01-19 14:18:37 -08003395 except AssertionError:
3396 main.log.exception( "" )
3397 return None
Jon Hall63604932015-02-26 17:09:50 -08003398 except TypeError:
3399 main.log.exception( self.name + ": Object not as expected" )
3400 return None
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003401 except pexpect.EOF:
3402 main.log.error( self.name + ": EOF exception found" )
3403 main.log.error( self.name + ": " + self.handle.before )
3404 main.cleanup()
3405 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003406 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003407 main.log.exception( self.name + ": Uncaught exception!" )
Hari Krishnaa43d4e92014-12-19 13:22:40 -08003408 main.cleanup()
3409 main.exit()
Jon Hall63604932015-02-26 17:09:50 -08003410
acsmarsa4a4d1e2015-07-10 16:01:24 -07003411 def leaderCandidates( self, jsonFormat=True ):
3412 """
3413 Returns the output of the leaders -c command.
3414 Optional argument:
3415 * jsonFormat - boolean indicating if you want output in json
3416 """
3417 try:
3418 cmdStr = "onos:leaders -c"
3419 if jsonFormat:
3420 cmdStr += " -j"
3421 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003422 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003423 assert "Command not found:" not in output, output
acsmarsa4a4d1e2015-07-10 16:01:24 -07003424 return output
Jon Hallc6793552016-01-19 14:18:37 -08003425 except AssertionError:
3426 main.log.exception( "" )
3427 return None
acsmarsa4a4d1e2015-07-10 16:01:24 -07003428 except TypeError:
3429 main.log.exception( self.name + ": Object not as expected" )
3430 return None
3431 except pexpect.EOF:
3432 main.log.error( self.name + ": EOF exception found" )
3433 main.log.error( self.name + ": " + self.handle.before )
3434 main.cleanup()
3435 main.exit()
3436 except Exception:
3437 main.log.exception( self.name + ": Uncaught exception!" )
3438 main.cleanup()
3439 main.exit()
3440
Jon Hallc6793552016-01-19 14:18:37 -08003441 def specificLeaderCandidate( self, topic ):
acsmarsa4a4d1e2015-07-10 16:01:24 -07003442 """
3443 Returns a list in format [leader,candidate1,candidate2,...] for a given
3444 topic parameter and an empty list if the topic doesn't exist
3445 If no leader is elected leader in the returned list will be "none"
3446 Returns None if there is a type error processing the json object
3447 """
3448 try:
Jon Hall6e709752016-02-01 13:38:46 -08003449 cmdStr = "onos:leaders -j"
Jon Hallc6793552016-01-19 14:18:37 -08003450 rawOutput = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003451 assert rawOutput is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003452 assert "Command not found:" not in rawOutput, rawOutput
3453 output = json.loads( rawOutput )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003454 results = []
3455 for dict in output:
3456 if dict["topic"] == topic:
3457 leader = dict["leader"]
Jon Hallc6793552016-01-19 14:18:37 -08003458 candidates = re.split( ", ", dict["candidates"][1:-1] )
3459 results.append( leader )
3460 results.extend( candidates )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003461 return results
Jon Hallc6793552016-01-19 14:18:37 -08003462 except AssertionError:
3463 main.log.exception( "" )
3464 return None
3465 except ( TypeError, ValueError ):
3466 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawOutput ) )
acsmarsa4a4d1e2015-07-10 16:01:24 -07003467 return None
3468 except pexpect.EOF:
3469 main.log.error( self.name + ": EOF exception found" )
3470 main.log.error( self.name + ": " + self.handle.before )
3471 main.cleanup()
3472 main.exit()
3473 except Exception:
3474 main.log.exception( self.name + ": Uncaught exception!" )
3475 main.cleanup()
3476 main.exit()
3477
Jon Hall61282e32015-03-19 11:34:11 -07003478 def pendingMap( self, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003479 """
3480 Returns the output of the intent Pending map.
3481 """
Jon Hall63604932015-02-26 17:09:50 -08003482 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003483 cmdStr = "onos:intents -p"
Jon Hall61282e32015-03-19 11:34:11 -07003484 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003485 cmdStr += " -j"
3486 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003487 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003488 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003489 return output
Jon Hallc6793552016-01-19 14:18:37 -08003490 except AssertionError:
3491 main.log.exception( "" )
3492 return None
Jon Hall63604932015-02-26 17:09:50 -08003493 except TypeError:
3494 main.log.exception( self.name + ": Object not as expected" )
3495 return None
3496 except pexpect.EOF:
3497 main.log.error( self.name + ": EOF exception found" )
3498 main.log.error( self.name + ": " + self.handle.before )
3499 main.cleanup()
3500 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003501 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003502 main.log.exception( self.name + ": Uncaught exception!" )
3503 main.cleanup()
3504 main.exit()
3505
Jon Hall2c8959e2016-12-16 12:17:34 -08003506 def partitions( self, candidates=False, jsonFormat=True ):
Jon Hall63604932015-02-26 17:09:50 -08003507 """
3508 Returns the output of the raft partitions command for ONOS.
3509 """
Jon Hall61282e32015-03-19 11:34:11 -07003510 # Sample JSON
3511 # {
3512 # "leader": "tcp://10.128.30.11:7238",
3513 # "members": [
3514 # "tcp://10.128.30.11:7238",
3515 # "tcp://10.128.30.17:7238",
3516 # "tcp://10.128.30.13:7238",
3517 # ],
3518 # "name": "p1",
3519 # "term": 3
3520 # },
Jon Hall63604932015-02-26 17:09:50 -08003521 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003522 cmdStr = "onos:partitions"
Jon Hall2c8959e2016-12-16 12:17:34 -08003523 if candidates:
3524 cmdStr += " -c"
Jon Hall61282e32015-03-19 11:34:11 -07003525 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003526 cmdStr += " -j"
3527 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003528 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003529 assert "Command not found:" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003530 return output
Jon Hallc6793552016-01-19 14:18:37 -08003531 except AssertionError:
3532 main.log.exception( "" )
3533 return None
Jon Hall63604932015-02-26 17:09:50 -08003534 except TypeError:
3535 main.log.exception( self.name + ": Object not as expected" )
3536 return None
3537 except pexpect.EOF:
3538 main.log.error( self.name + ": EOF exception found" )
3539 main.log.error( self.name + ": " + self.handle.before )
3540 main.cleanup()
3541 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003542 except Exception:
Jon Hall63604932015-02-26 17:09:50 -08003543 main.log.exception( self.name + ": Uncaught exception!" )
3544 main.cleanup()
3545 main.exit()
3546
Jon Halle9f909e2016-09-23 10:43:12 -07003547 def apps( self, summary=False, active=False, jsonFormat=True ):
Jon Hallbe379602015-03-24 13:39:32 -07003548 """
3549 Returns the output of the apps command for ONOS. This command lists
3550 information about installed ONOS applications
3551 """
3552 # Sample JSON object
3553 # [{"name":"org.onosproject.openflow","id":0,"version":"1.2.0",
3554 # "description":"ONOS OpenFlow protocol southbound providers",
3555 # "origin":"ON.Lab","permissions":"[]","featuresRepo":"",
3556 # "features":"[onos-openflow]","state":"ACTIVE"}]
3557 try:
Jon Hallc6358dd2015-04-10 12:44:28 -07003558 cmdStr = "onos:apps"
Jon Halle9f909e2016-09-23 10:43:12 -07003559 if summary:
3560 cmdStr += " -s"
3561 if active:
3562 cmdStr += " -a"
Jon Hallbe379602015-03-24 13:39:32 -07003563 if jsonFormat:
Jon Hallc6358dd2015-04-10 12:44:28 -07003564 cmdStr += " -j"
3565 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003566 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003567 assert "Command not found:" not in output, output
3568 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003569 return output
Jon Hallbe379602015-03-24 13:39:32 -07003570 # FIXME: look at specific exceptions/Errors
3571 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003572 main.log.exception( "Error in processing onos:app command." )
Jon Hallbe379602015-03-24 13:39:32 -07003573 return None
3574 except TypeError:
3575 main.log.exception( self.name + ": Object not as expected" )
3576 return None
3577 except pexpect.EOF:
3578 main.log.error( self.name + ": EOF exception found" )
3579 main.log.error( self.name + ": " + self.handle.before )
3580 main.cleanup()
3581 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003582 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003583 main.log.exception( self.name + ": Uncaught exception!" )
3584 main.cleanup()
3585 main.exit()
3586
Jon Hall146f1522015-03-24 15:33:24 -07003587 def appStatus( self, appName ):
3588 """
3589 Uses the onos:apps cli command to return the status of an application.
3590 Returns:
3591 "ACTIVE" - If app is installed and activated
3592 "INSTALLED" - If app is installed and deactivated
3593 "UNINSTALLED" - If app is not installed
3594 None - on error
3595 """
Jon Hall146f1522015-03-24 15:33:24 -07003596 try:
3597 if not isinstance( appName, types.StringType ):
3598 main.log.error( self.name + ".appStatus(): appName must be" +
3599 " a string" )
3600 return None
3601 output = self.apps( jsonFormat=True )
3602 appsJson = json.loads( output )
3603 state = None
3604 for app in appsJson:
3605 if appName == app.get('name'):
3606 state = app.get('state')
3607 break
3608 if state == "ACTIVE" or state == "INSTALLED":
3609 return state
3610 elif state is None:
3611 return "UNINSTALLED"
3612 elif state:
3613 main.log.error( "Unexpected state from 'onos:apps': " +
3614 str( state ) )
3615 return state
Jon Hallc6793552016-01-19 14:18:37 -08003616 except ( TypeError, ValueError ):
3617 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003618 return None
3619 except pexpect.EOF:
3620 main.log.error( self.name + ": EOF exception found" )
3621 main.log.error( self.name + ": " + self.handle.before )
3622 main.cleanup()
3623 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003624 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003625 main.log.exception( self.name + ": Uncaught exception!" )
3626 main.cleanup()
3627 main.exit()
3628
Jon Hallbe379602015-03-24 13:39:32 -07003629 def app( self, appName, option ):
3630 """
3631 Interacts with the app command for ONOS. This command manages
3632 application inventory.
3633 """
Jon Hallbe379602015-03-24 13:39:32 -07003634 try:
Jon Hallbd16b922015-03-26 17:53:15 -07003635 # Validate argument types
3636 valid = True
3637 if not isinstance( appName, types.StringType ):
3638 main.log.error( self.name + ".app(): appName must be a " +
3639 "string" )
3640 valid = False
3641 if not isinstance( option, types.StringType ):
3642 main.log.error( self.name + ".app(): option must be a string" )
3643 valid = False
3644 if not valid:
3645 return main.FALSE
3646 # Validate Option
3647 option = option.lower()
3648 # NOTE: Install may become a valid option
3649 if option == "activate":
3650 pass
3651 elif option == "deactivate":
3652 pass
3653 elif option == "uninstall":
3654 pass
3655 else:
3656 # Invalid option
3657 main.log.error( "The ONOS app command argument only takes " +
3658 "the values: (activate|deactivate|uninstall)" +
3659 "; was given '" + option + "'")
3660 return main.FALSE
Jon Hall146f1522015-03-24 15:33:24 -07003661 cmdStr = "onos:app " + option + " " + appName
Jon Hallbe379602015-03-24 13:39:32 -07003662 output = self.sendline( cmdStr )
You Wangb5a55f72017-03-03 12:51:05 -08003663 assert output is not None, "Error in sendline"
3664 assert "Command not found:" not in output, output
Jon Hallbe379602015-03-24 13:39:32 -07003665 if "Error executing command" in output:
3666 main.log.error( "Error in processing onos:app command: " +
3667 str( output ) )
Jon Hall146f1522015-03-24 15:33:24 -07003668 return main.FALSE
Jon Hallbe379602015-03-24 13:39:32 -07003669 elif "No such application" in output:
3670 main.log.error( "The application '" + appName +
3671 "' is not installed in ONOS" )
Jon Hall146f1522015-03-24 15:33:24 -07003672 return main.FALSE
3673 elif "Command not found:" in output:
3674 main.log.error( "Error in processing onos:app command: " +
3675 str( output ) )
3676 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003677 elif "Unsupported command:" in output:
3678 main.log.error( "Incorrect command given to 'app': " +
3679 str( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003680 # NOTE: we may need to add more checks here
Jon Hallbd16b922015-03-26 17:53:15 -07003681 # else: Command was successful
Jon Hall08f61bc2015-04-13 16:00:30 -07003682 # main.log.debug( "app response: " + repr( output ) )
Jon Hallbe379602015-03-24 13:39:32 -07003683 return main.TRUE
You Wangb5a55f72017-03-03 12:51:05 -08003684 except AssertionError:
3685 main.log.exception( self.name + ": AssertionError exception found" )
3686 return main.ERROR
Jon Hallbe379602015-03-24 13:39:32 -07003687 except TypeError:
3688 main.log.exception( self.name + ": Object not as expected" )
3689 return main.ERROR
3690 except pexpect.EOF:
3691 main.log.error( self.name + ": EOF exception found" )
3692 main.log.error( self.name + ": " + self.handle.before )
3693 main.cleanup()
3694 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003695 except Exception:
Jon Hallbe379602015-03-24 13:39:32 -07003696 main.log.exception( self.name + ": Uncaught exception!" )
3697 main.cleanup()
3698 main.exit()
Jon Hall146f1522015-03-24 15:33:24 -07003699
Jon Hallbd16b922015-03-26 17:53:15 -07003700 def activateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003701 """
3702 Activate an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003703 appName is the hierarchical app name, not the feature name
3704 If check is True, method will check the status of the app after the
3705 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003706 Returns main.TRUE if the command was successfully sent
3707 main.FALSE if the cli responded with an error or given
3708 incorrect input
3709 """
3710 try:
3711 if not isinstance( appName, types.StringType ):
3712 main.log.error( self.name + ".activateApp(): appName must be" +
3713 " a string" )
3714 return main.FALSE
3715 status = self.appStatus( appName )
3716 if status == "INSTALLED":
3717 response = self.app( appName, "activate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003718 if check and response == main.TRUE:
3719 for i in range(10): # try 10 times then give up
Jon Hallbd16b922015-03-26 17:53:15 -07003720 status = self.appStatus( appName )
3721 if status == "ACTIVE":
3722 return main.TRUE
3723 else:
Jon Hall050e1bd2015-03-30 13:33:02 -07003724 main.log.debug( "The state of application " +
3725 appName + " is " + status )
Jon Hallbd16b922015-03-26 17:53:15 -07003726 time.sleep( 1 )
3727 return main.FALSE
3728 else: # not 'check' or command didn't succeed
3729 return response
Jon Hall146f1522015-03-24 15:33:24 -07003730 elif status == "ACTIVE":
3731 return main.TRUE
3732 elif status == "UNINSTALLED":
3733 main.log.error( self.name + ": Tried to activate the " +
3734 "application '" + appName + "' which is not " +
3735 "installed." )
3736 else:
3737 main.log.error( "Unexpected return value from appStatus: " +
3738 str( status ) )
3739 return main.ERROR
3740 except TypeError:
3741 main.log.exception( self.name + ": Object not as expected" )
3742 return main.ERROR
3743 except pexpect.EOF:
3744 main.log.error( self.name + ": EOF exception found" )
3745 main.log.error( self.name + ": " + self.handle.before )
3746 main.cleanup()
3747 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003748 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003749 main.log.exception( self.name + ": Uncaught exception!" )
3750 main.cleanup()
3751 main.exit()
3752
Jon Hallbd16b922015-03-26 17:53:15 -07003753 def deactivateApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003754 """
3755 Deactivate an app that is already activated in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003756 appName is the hierarchical app name, not the feature name
3757 If check is True, method will check the status of the app after the
3758 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003759 Returns main.TRUE if the command was successfully sent
3760 main.FALSE if the cli responded with an error or given
3761 incorrect input
3762 """
3763 try:
3764 if not isinstance( appName, types.StringType ):
3765 main.log.error( self.name + ".deactivateApp(): appName must " +
3766 "be a string" )
3767 return main.FALSE
3768 status = self.appStatus( appName )
3769 if status == "INSTALLED":
3770 return main.TRUE
3771 elif status == "ACTIVE":
3772 response = self.app( appName, "deactivate" )
Jon Hallbd16b922015-03-26 17:53:15 -07003773 if check and response == main.TRUE:
3774 for i in range(10): # try 10 times then give up
3775 status = self.appStatus( appName )
3776 if status == "INSTALLED":
3777 return main.TRUE
3778 else:
3779 time.sleep( 1 )
3780 return main.FALSE
3781 else: # not check or command didn't succeed
3782 return response
Jon Hall146f1522015-03-24 15:33:24 -07003783 elif status == "UNINSTALLED":
3784 main.log.warn( self.name + ": Tried to deactivate the " +
3785 "application '" + appName + "' which is not " +
3786 "installed." )
3787 return main.TRUE
3788 else:
3789 main.log.error( "Unexpected return value from appStatus: " +
3790 str( status ) )
3791 return main.ERROR
3792 except TypeError:
3793 main.log.exception( self.name + ": Object not as expected" )
3794 return main.ERROR
3795 except pexpect.EOF:
3796 main.log.error( self.name + ": EOF exception found" )
3797 main.log.error( self.name + ": " + self.handle.before )
3798 main.cleanup()
3799 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003800 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003801 main.log.exception( self.name + ": Uncaught exception!" )
3802 main.cleanup()
3803 main.exit()
3804
Jon Hallbd16b922015-03-26 17:53:15 -07003805 def uninstallApp( self, appName, check=True ):
Jon Hall146f1522015-03-24 15:33:24 -07003806 """
3807 Uninstall an app that is already installed in ONOS
Jon Hallbd16b922015-03-26 17:53:15 -07003808 appName is the hierarchical app name, not the feature name
3809 If check is True, method will check the status of the app after the
3810 command is issued
Jon Hall146f1522015-03-24 15:33:24 -07003811 Returns main.TRUE if the command was successfully sent
3812 main.FALSE if the cli responded with an error or given
3813 incorrect input
3814 """
3815 # TODO: check with Thomas about the state machine for apps
3816 try:
3817 if not isinstance( appName, types.StringType ):
3818 main.log.error( self.name + ".uninstallApp(): appName must " +
3819 "be a string" )
3820 return main.FALSE
3821 status = self.appStatus( appName )
3822 if status == "INSTALLED":
3823 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003824 if check and response == main.TRUE:
3825 for i in range(10): # try 10 times then give up
3826 status = self.appStatus( appName )
3827 if status == "UNINSTALLED":
3828 return main.TRUE
3829 else:
3830 time.sleep( 1 )
3831 return main.FALSE
3832 else: # not check or command didn't succeed
3833 return response
Jon Hall146f1522015-03-24 15:33:24 -07003834 elif status == "ACTIVE":
3835 main.log.warn( self.name + ": Tried to uninstall the " +
3836 "application '" + appName + "' which is " +
3837 "currently active." )
3838 response = self.app( appName, "uninstall" )
Jon Hallbd16b922015-03-26 17:53:15 -07003839 if check and response == main.TRUE:
3840 for i in range(10): # try 10 times then give up
3841 status = self.appStatus( appName )
3842 if status == "UNINSTALLED":
3843 return main.TRUE
3844 else:
3845 time.sleep( 1 )
3846 return main.FALSE
3847 else: # not check or command didn't succeed
3848 return response
Jon Hall146f1522015-03-24 15:33:24 -07003849 elif status == "UNINSTALLED":
3850 return main.TRUE
3851 else:
3852 main.log.error( "Unexpected return value from appStatus: " +
3853 str( status ) )
3854 return main.ERROR
3855 except TypeError:
3856 main.log.exception( self.name + ": Object not as expected" )
3857 return main.ERROR
3858 except pexpect.EOF:
3859 main.log.error( self.name + ": EOF exception found" )
3860 main.log.error( self.name + ": " + self.handle.before )
3861 main.cleanup()
3862 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003863 except Exception:
Jon Hall146f1522015-03-24 15:33:24 -07003864 main.log.exception( self.name + ": Uncaught exception!" )
3865 main.cleanup()
3866 main.exit()
Jon Hallbd16b922015-03-26 17:53:15 -07003867
3868 def appIDs( self, jsonFormat=True ):
3869 """
3870 Show the mappings between app id and app names given by the 'app-ids'
3871 cli command
3872 """
3873 try:
3874 cmdStr = "app-ids"
3875 if jsonFormat:
3876 cmdStr += " -j"
Jon Hallc6358dd2015-04-10 12:44:28 -07003877 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07003878 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08003879 assert "Command not found:" not in output, output
3880 assert "Error executing command" not in output, output
Jon Hallc6358dd2015-04-10 12:44:28 -07003881 return output
Jon Hallbd16b922015-03-26 17:53:15 -07003882 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08003883 main.log.exception( "Error in processing onos:app-ids command." )
Jon Hallbd16b922015-03-26 17:53:15 -07003884 return None
3885 except TypeError:
3886 main.log.exception( self.name + ": Object not as expected" )
3887 return None
3888 except pexpect.EOF:
3889 main.log.error( self.name + ": EOF exception found" )
3890 main.log.error( self.name + ": " + self.handle.before )
3891 main.cleanup()
3892 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003893 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003894 main.log.exception( self.name + ": Uncaught exception!" )
3895 main.cleanup()
3896 main.exit()
3897
3898 def appToIDCheck( self ):
3899 """
3900 This method will check that each application's ID listed in 'apps' is
3901 the same as the ID listed in 'app-ids'. The check will also check that
3902 there are no duplicate IDs issued. Note that an app ID should be
3903 a globaly unique numerical identifier for app/app-like features. Once
3904 an ID is registered, the ID is never freed up so that if an app is
3905 reinstalled it will have the same ID.
3906
3907 Returns: main.TRUE if the check passes and
3908 main.FALSE if the check fails or
3909 main.ERROR if there is some error in processing the test
3910 """
3911 try:
Jon Hall390696c2015-05-05 17:13:41 -07003912 bail = False
Jon Hallc6793552016-01-19 14:18:37 -08003913 rawJson = self.appIDs( jsonFormat=True )
3914 if rawJson:
3915 ids = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003916 else:
Jon Hallc6793552016-01-19 14:18:37 -08003917 main.log.error( "app-ids returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003918 bail = True
Jon Hallc6793552016-01-19 14:18:37 -08003919 rawJson = self.apps( jsonFormat=True )
3920 if rawJson:
3921 apps = json.loads( rawJson )
Jon Hall390696c2015-05-05 17:13:41 -07003922 else:
Jon Hallc6793552016-01-19 14:18:37 -08003923 main.log.error( "apps returned nothing:" + repr( rawJson ) )
Jon Hall390696c2015-05-05 17:13:41 -07003924 bail = True
3925 if bail:
3926 return main.FALSE
Jon Hallbd16b922015-03-26 17:53:15 -07003927 result = main.TRUE
3928 for app in apps:
3929 appID = app.get( 'id' )
3930 if appID is None:
3931 main.log.error( "Error parsing app: " + str( app ) )
3932 result = main.FALSE
3933 appName = app.get( 'name' )
3934 if appName is None:
3935 main.log.error( "Error parsing app: " + str( app ) )
3936 result = main.FALSE
3937 # get the entry in ids that has the same appID
Jon Hall390696c2015-05-05 17:13:41 -07003938 current = filter( lambda item: item[ 'id' ] == appID, ids )
Jon Hall050e1bd2015-03-30 13:33:02 -07003939 # main.log.debug( "Comparing " + str( app ) + " to " +
3940 # str( current ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003941 if not current: # if ids doesn't have this id
3942 result = main.FALSE
3943 main.log.error( "'app-ids' does not have the ID for " +
3944 str( appName ) + " that apps does." )
3945 elif len( current ) > 1:
3946 # there is more than one app with this ID
3947 result = main.FALSE
3948 # We will log this later in the method
3949 elif not current[0][ 'name' ] == appName:
3950 currentName = current[0][ 'name' ]
3951 result = main.FALSE
3952 main.log.error( "'app-ids' has " + str( currentName ) +
3953 " registered under id:" + str( appID ) +
3954 " but 'apps' has " + str( appName ) )
3955 else:
3956 pass # id and name match!
3957 # now make sure that app-ids has no duplicates
3958 idsList = []
3959 namesList = []
3960 for item in ids:
3961 idsList.append( item[ 'id' ] )
3962 namesList.append( item[ 'name' ] )
3963 if len( idsList ) != len( set( idsList ) ) or\
3964 len( namesList ) != len( set( namesList ) ):
3965 main.log.error( "'app-ids' has some duplicate entries: \n"
3966 + json.dumps( ids,
3967 sort_keys=True,
3968 indent=4,
3969 separators=( ',', ': ' ) ) )
3970 result = main.FALSE
3971 return result
Jon Hallc6793552016-01-19 14:18:37 -08003972 except ( TypeError, ValueError ):
3973 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, rawJson ) )
Jon Hallbd16b922015-03-26 17:53:15 -07003974 return main.ERROR
3975 except pexpect.EOF:
3976 main.log.error( self.name + ": EOF exception found" )
3977 main.log.error( self.name + ": " + self.handle.before )
3978 main.cleanup()
3979 main.exit()
Jon Hall77ba41c2015-04-06 10:25:40 -07003980 except Exception:
Jon Hallbd16b922015-03-26 17:53:15 -07003981 main.log.exception( self.name + ": Uncaught exception!" )
3982 main.cleanup()
3983 main.exit()
3984
Jon Hallfb760a02015-04-13 15:35:03 -07003985 def getCfg( self, component=None, propName=None, short=False,
3986 jsonFormat=True ):
3987 """
3988 Get configuration settings from onos cli
3989 Optional arguments:
3990 component - Optionally only list configurations for a specific
3991 component. If None, all components with configurations
3992 are displayed. Case Sensitive string.
3993 propName - If component is specified, propName option will show
3994 only this specific configuration from that component.
3995 Case Sensitive string.
3996 jsonFormat - Returns output as json. Note that this will override
3997 the short option
3998 short - Short, less verbose, version of configurations.
3999 This is overridden by the json option
4000 returns:
4001 Output from cli as a string or None on error
4002 """
4003 try:
4004 baseStr = "cfg"
4005 cmdStr = " get"
4006 componentStr = ""
4007 if component:
4008 componentStr += " " + component
4009 if propName:
4010 componentStr += " " + propName
4011 if jsonFormat:
4012 baseStr += " -j"
4013 elif short:
4014 baseStr += " -s"
4015 output = self.sendline( baseStr + cmdStr + componentStr )
Jon Halla495f562016-05-16 18:03:26 -07004016 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004017 assert "Command not found:" not in output, output
4018 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004019 return output
4020 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004021 main.log.exception( "Error in processing 'cfg get' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004022 return None
4023 except TypeError:
4024 main.log.exception( self.name + ": Object not as expected" )
4025 return None
4026 except pexpect.EOF:
4027 main.log.error( self.name + ": EOF exception found" )
4028 main.log.error( self.name + ": " + self.handle.before )
4029 main.cleanup()
4030 main.exit()
4031 except Exception:
4032 main.log.exception( self.name + ": Uncaught exception!" )
4033 main.cleanup()
4034 main.exit()
4035
4036 def setCfg( self, component, propName, value=None, check=True ):
4037 """
4038 Set/Unset configuration settings from ONOS cli
Jon Hall390696c2015-05-05 17:13:41 -07004039 Required arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004040 component - The case sensitive name of the component whose
4041 property is to be set
4042 propName - The case sensitive name of the property to be set/unset
Jon Hall390696c2015-05-05 17:13:41 -07004043 Optional arguments:
Jon Hallfb760a02015-04-13 15:35:03 -07004044 value - The value to set the property to. If None, will unset the
4045 property and revert it to it's default value(if applicable)
4046 check - Boolean, Check whether the option was successfully set this
4047 only applies when a value is given.
4048 returns:
4049 main.TRUE on success or main.FALSE on failure. If check is False,
4050 will return main.TRUE unless there is an error
4051 """
4052 try:
4053 baseStr = "cfg"
4054 cmdStr = " set " + str( component ) + " " + str( propName )
4055 if value is not None:
4056 cmdStr += " " + str( value )
4057 output = self.sendline( baseStr + cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004058 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004059 assert "Command not found:" not in output, output
4060 assert "Error executing command" not in output, output
Jon Hallfb760a02015-04-13 15:35:03 -07004061 if value and check:
4062 results = self.getCfg( component=str( component ),
4063 propName=str( propName ),
4064 jsonFormat=True )
4065 # Check if current value is what we just set
4066 try:
4067 jsonOutput = json.loads( results )
4068 current = jsonOutput[ 'value' ]
Jon Hallc6793552016-01-19 14:18:37 -08004069 except ( TypeError, ValueError ):
Jon Hallfb760a02015-04-13 15:35:03 -07004070 main.log.exception( "Error parsing cfg output" )
4071 main.log.error( "output:" + repr( results ) )
4072 return main.FALSE
4073 if current == str( value ):
4074 return main.TRUE
4075 return main.FALSE
4076 return main.TRUE
4077 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004078 main.log.exception( "Error in processing 'cfg set' command." )
Jon Hallfb760a02015-04-13 15:35:03 -07004079 return main.FALSE
Jon Hallc6793552016-01-19 14:18:37 -08004080 except ( TypeError, ValueError ):
4081 main.log.exception( "{}: Object not as expected: {!r}".format( self.name, results ) )
Jon Hallfb760a02015-04-13 15:35:03 -07004082 return main.FALSE
4083 except pexpect.EOF:
4084 main.log.error( self.name + ": EOF exception found" )
4085 main.log.error( self.name + ": " + self.handle.before )
4086 main.cleanup()
4087 main.exit()
4088 except Exception:
4089 main.log.exception( self.name + ": Uncaught exception!" )
4090 main.cleanup()
4091 main.exit()
4092
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004093 def distPrimitivesSend( self, cmd ):
4094 """
4095 Function to handle sending cli commands for the distributed primitives test app
4096
4097 This command will catch some exceptions and retry the command on some
4098 specific store exceptions.
4099
4100 Required arguments:
4101 cmd - The command to send to the cli
4102 returns:
4103 string containing the cli output
4104 None on Error
4105 """
4106 try:
4107 output = self.sendline( cmd )
4108 try:
4109 assert output is not None, "Error in sendline"
4110 # TODO: Maybe make this less hardcoded
4111 # ConsistentMap Exceptions
4112 assert "org.onosproject.store.service" not in output
4113 # Node not leader
4114 assert "java.lang.IllegalStateException" not in output
4115 except AssertionError:
4116 main.log.error( "Error in processing '" + cmd + "' " +
4117 "command: " + str( output ) )
4118 retryTime = 30 # Conservative time, given by Madan
4119 main.log.info( "Waiting " + str( retryTime ) +
4120 "seconds before retrying." )
4121 time.sleep( retryTime ) # Due to change in mastership
4122 output = self.sendline( cmd )
4123 assert output is not None, "Error in sendline"
4124 assert "Command not found:" not in output, output
4125 assert "Error executing command" not in output, output
4126 main.log.info( self.name + ": " + output )
4127 return output
4128 except AssertionError:
4129 main.log.exception( "Error in processing '" + cmd + "' command." )
4130 return None
4131 except TypeError:
4132 main.log.exception( self.name + ": Object not as expected" )
4133 return None
4134 except pexpect.EOF:
4135 main.log.error( self.name + ": EOF exception found" )
4136 main.log.error( self.name + ": " + self.handle.before )
4137 main.cleanup()
4138 main.exit()
4139 except Exception:
4140 main.log.exception( self.name + ": Uncaught exception!" )
4141 main.cleanup()
4142 main.exit()
4143
Jon Hall390696c2015-05-05 17:13:41 -07004144 def setTestAdd( self, setName, values ):
4145 """
4146 CLI command to add elements to a distributed set.
4147 Arguments:
4148 setName - The name of the set to add to.
4149 values - The value(s) to add to the set, space seperated.
4150 Example usages:
4151 setTestAdd( "set1", "a b c" )
4152 setTestAdd( "set2", "1" )
4153 returns:
4154 main.TRUE on success OR
4155 main.FALSE if elements were already in the set OR
4156 main.ERROR on error
4157 """
4158 try:
4159 cmdStr = "set-test-add " + str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004160 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004161 positiveMatch = "\[(.*)\] was added to the set " + str( setName )
4162 negativeMatch = "\[(.*)\] was already in set " + str( setName )
Jon Hall390696c2015-05-05 17:13:41 -07004163 if re.search( positiveMatch, output):
4164 return main.TRUE
4165 elif re.search( negativeMatch, output):
4166 return main.FALSE
4167 else:
4168 main.log.error( self.name + ": setTestAdd did not" +
4169 " match expected output" )
Jon Hall390696c2015-05-05 17:13:41 -07004170 main.log.debug( self.name + " actual: " + repr( output ) )
4171 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004172 except TypeError:
4173 main.log.exception( self.name + ": Object not as expected" )
4174 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004175 except Exception:
4176 main.log.exception( self.name + ": Uncaught exception!" )
4177 main.cleanup()
4178 main.exit()
4179
4180 def setTestRemove( self, setName, values, clear=False, retain=False ):
4181 """
4182 CLI command to remove elements from a distributed set.
4183 Required arguments:
4184 setName - The name of the set to remove from.
4185 values - The value(s) to remove from the set, space seperated.
4186 Optional arguments:
4187 clear - Clear all elements from the set
4188 retain - Retain only the given values. (intersection of the
4189 original set and the given set)
4190 returns:
4191 main.TRUE on success OR
4192 main.FALSE if the set was not changed OR
4193 main.ERROR on error
4194 """
4195 try:
4196 cmdStr = "set-test-remove "
4197 if clear:
4198 cmdStr += "-c " + str( setName )
4199 elif retain:
4200 cmdStr += "-r " + str( setName ) + " " + str( values )
4201 else:
4202 cmdStr += str( setName ) + " " + str( values )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004203 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004204 if clear:
4205 pattern = "Set " + str( setName ) + " cleared"
4206 if re.search( pattern, output ):
4207 return main.TRUE
4208 elif retain:
4209 positivePattern = str( setName ) + " was pruned to contain " +\
4210 "only elements of set \[(.*)\]"
4211 negativePattern = str( setName ) + " was not changed by " +\
4212 "retaining only elements of the set " +\
4213 "\[(.*)\]"
4214 if re.search( positivePattern, output ):
4215 return main.TRUE
4216 elif re.search( negativePattern, output ):
4217 return main.FALSE
4218 else:
4219 positivePattern = "\[(.*)\] was removed from the set " +\
4220 str( setName )
4221 if ( len( values.split() ) == 1 ):
4222 negativePattern = "\[(.*)\] was not in set " +\
4223 str( setName )
4224 else:
4225 negativePattern = "No element of \[(.*)\] was in set " +\
4226 str( setName )
4227 if re.search( positivePattern, output ):
4228 return main.TRUE
4229 elif re.search( negativePattern, output ):
4230 return main.FALSE
4231 main.log.error( self.name + ": setTestRemove did not" +
4232 " match expected output" )
4233 main.log.debug( self.name + " expected: " + pattern )
4234 main.log.debug( self.name + " actual: " + repr( output ) )
4235 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004236 except TypeError:
4237 main.log.exception( self.name + ": Object not as expected" )
4238 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004239 except Exception:
4240 main.log.exception( self.name + ": Uncaught exception!" )
4241 main.cleanup()
4242 main.exit()
4243
4244 def setTestGet( self, setName, values="" ):
4245 """
4246 CLI command to get the elements in a distributed set.
4247 Required arguments:
4248 setName - The name of the set to remove from.
4249 Optional arguments:
4250 values - The value(s) to check if in the set, space seperated.
4251 returns:
4252 main.ERROR on error OR
4253 A list of elements in the set if no optional arguments are
4254 supplied OR
4255 A tuple containing the list then:
4256 main.FALSE if the given values are not in the set OR
4257 main.TRUE if the given values are in the set OR
4258 """
4259 try:
4260 values = str( values ).strip()
4261 setName = str( setName ).strip()
4262 length = len( values.split() )
4263 containsCheck = None
4264 # Patterns to match
4265 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004266 pattern = "Items in set " + setName + ":\r\n" + setPattern
Jon Hall390696c2015-05-05 17:13:41 -07004267 containsTrue = "Set " + setName + " contains the value " + values
4268 containsFalse = "Set " + setName + " did not contain the value " +\
4269 values
4270 containsAllTrue = "Set " + setName + " contains the the subset " +\
4271 setPattern
4272 containsAllFalse = "Set " + setName + " did not contain the the" +\
4273 " subset " + setPattern
4274
4275 cmdStr = "set-test-get "
4276 cmdStr += setName + " " + values
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004277 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004278 if length == 0:
4279 match = re.search( pattern, output )
4280 else: # if given values
4281 if length == 1: # Contains output
Jon Hall54b994f2016-12-05 10:48:59 -08004282 patternTrue = pattern + "\r\n" + containsTrue
4283 patternFalse = pattern + "\r\n" + containsFalse
Jon Hall390696c2015-05-05 17:13:41 -07004284 else: # ContainsAll output
Jon Hall54b994f2016-12-05 10:48:59 -08004285 patternTrue = pattern + "\r\n" + containsAllTrue
4286 patternFalse = pattern + "\r\n" + containsAllFalse
Jon Hall390696c2015-05-05 17:13:41 -07004287 matchTrue = re.search( patternTrue, output )
4288 matchFalse = re.search( patternFalse, output )
4289 if matchTrue:
4290 containsCheck = main.TRUE
4291 match = matchTrue
4292 elif matchFalse:
4293 containsCheck = main.FALSE
4294 match = matchFalse
4295 else:
Jon Halle0f0b342017-04-18 11:43:47 -07004296 main.log.error( self.name + " setTestGet did not match " +
Jon Hall390696c2015-05-05 17:13:41 -07004297 "expected output" )
4298 main.log.debug( self.name + " expected: " + pattern )
4299 main.log.debug( self.name + " actual: " + repr( output ) )
4300 match = None
4301 if match:
4302 setMatch = match.group( 1 )
4303 if setMatch == '':
4304 setList = []
4305 else:
4306 setList = setMatch.split( ", " )
4307 if length > 0:
4308 return ( setList, containsCheck )
4309 else:
4310 return setList
4311 else: # no match
4312 main.log.error( self.name + ": setTestGet did not" +
4313 " match expected output" )
4314 main.log.debug( self.name + " expected: " + pattern )
4315 main.log.debug( self.name + " actual: " + repr( output ) )
4316 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004317 except TypeError:
4318 main.log.exception( self.name + ": Object not as expected" )
4319 return main.ERROR
Jon Hall390696c2015-05-05 17:13:41 -07004320 except Exception:
4321 main.log.exception( self.name + ": Uncaught exception!" )
4322 main.cleanup()
4323 main.exit()
4324
4325 def setTestSize( self, setName ):
4326 """
4327 CLI command to get the elements in a distributed set.
4328 Required arguments:
4329 setName - The name of the set to remove from.
4330 returns:
Jon Hallfeff3082015-05-19 10:23:26 -07004331 The integer value of the size returned or
Jon Hall390696c2015-05-05 17:13:41 -07004332 None on error
4333 """
4334 try:
4335 # TODO: Should this check against the number of elements returned
4336 # and then return true/false based on that?
4337 setName = str( setName ).strip()
4338 # Patterns to match
4339 setPattern = "\[(.*)\]"
Jon Hall67253832016-12-05 09:47:13 -08004340 pattern = "There are (\d+) items in set " + setName + ":\r\n" +\
Jon Hall390696c2015-05-05 17:13:41 -07004341 setPattern
4342 cmdStr = "set-test-get -s "
4343 cmdStr += setName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004344 output = self.distPrimitivesSend( cmdStr )
Jon Hall390696c2015-05-05 17:13:41 -07004345 match = re.search( pattern, output )
4346 if match:
4347 setSize = int( match.group( 1 ) )
4348 setMatch = match.group( 2 )
4349 if len( setMatch.split() ) == setSize:
4350 main.log.info( "The size returned by " + self.name +
4351 " matches the number of elements in " +
4352 "the returned set" )
4353 else:
4354 main.log.error( "The size returned by " + self.name +
4355 " does not match the number of " +
4356 "elements in the returned set." )
4357 return setSize
4358 else: # no match
4359 main.log.error( self.name + ": setTestGet did not" +
4360 " match expected output" )
4361 main.log.debug( self.name + " expected: " + pattern )
4362 main.log.debug( self.name + " actual: " + repr( output ) )
4363 return None
Jon Hall390696c2015-05-05 17:13:41 -07004364 except TypeError:
4365 main.log.exception( self.name + ": Object not as expected" )
4366 return None
Jon Hall390696c2015-05-05 17:13:41 -07004367 except Exception:
4368 main.log.exception( self.name + ": Uncaught exception!" )
4369 main.cleanup()
4370 main.exit()
4371
Jon Hall80daded2015-05-27 16:07:00 -07004372 def counters( self, jsonFormat=True ):
Jon Hall390696c2015-05-05 17:13:41 -07004373 """
4374 Command to list the various counters in the system.
4375 returns:
Jon Hall80daded2015-05-27 16:07:00 -07004376 if jsonFormat, a string of the json object returned by the cli
4377 command
4378 if not jsonFormat, the normal string output of the cli command
Jon Hall390696c2015-05-05 17:13:41 -07004379 None on error
4380 """
Jon Hall390696c2015-05-05 17:13:41 -07004381 try:
Jon Hall390696c2015-05-05 17:13:41 -07004382 cmdStr = "counters"
Jon Hall80daded2015-05-27 16:07:00 -07004383 if jsonFormat:
4384 cmdStr += " -j"
Jon Hall390696c2015-05-05 17:13:41 -07004385 output = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004386 assert output is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004387 assert "Command not found:" not in output, output
4388 assert "Error executing command" not in output, output
Jon Hall390696c2015-05-05 17:13:41 -07004389 main.log.info( self.name + ": " + output )
Jon Hall80daded2015-05-27 16:07:00 -07004390 return output
Jon Hall390696c2015-05-05 17:13:41 -07004391 except AssertionError:
Jon Hallc6793552016-01-19 14:18:37 -08004392 main.log.exception( "Error in processing 'counters' command." )
Jon Hall80daded2015-05-27 16:07:00 -07004393 return None
Jon Hall390696c2015-05-05 17:13:41 -07004394 except TypeError:
4395 main.log.exception( self.name + ": Object not as expected" )
Jon Hall80daded2015-05-27 16:07:00 -07004396 return None
Jon Hall390696c2015-05-05 17:13:41 -07004397 except pexpect.EOF:
4398 main.log.error( self.name + ": EOF exception found" )
4399 main.log.error( self.name + ": " + self.handle.before )
4400 main.cleanup()
4401 main.exit()
4402 except Exception:
4403 main.log.exception( self.name + ": Uncaught exception!" )
4404 main.cleanup()
4405 main.exit()
4406
Jon Hall935db192016-04-19 00:22:04 -07004407 def counterTestAddAndGet( self, counter, delta=1 ):
Jon Hall390696c2015-05-05 17:13:41 -07004408 """
Jon Halle1a3b752015-07-22 13:02:46 -07004409 CLI command to add a delta to then get a distributed counter.
Jon Hall390696c2015-05-05 17:13:41 -07004410 Required arguments:
4411 counter - The name of the counter to increment.
4412 Optional arguments:
Jon Halle1a3b752015-07-22 13:02:46 -07004413 delta - The long to add to the counter
Jon Hall390696c2015-05-05 17:13:41 -07004414 returns:
4415 integer value of the counter or
4416 None on Error
4417 """
4418 try:
4419 counter = str( counter )
Jon Halle1a3b752015-07-22 13:02:46 -07004420 delta = int( delta )
Jon Hall390696c2015-05-05 17:13:41 -07004421 cmdStr = "counter-test-increment "
Jon Hall390696c2015-05-05 17:13:41 -07004422 cmdStr += counter
Jon Halle1a3b752015-07-22 13:02:46 -07004423 if delta != 1:
4424 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004425 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004426 pattern = counter + " was updated to (-?\d+)"
Jon Hall390696c2015-05-05 17:13:41 -07004427 match = re.search( pattern, output )
4428 if match:
4429 return int( match.group( 1 ) )
4430 else:
Jon Halle1a3b752015-07-22 13:02:46 -07004431 main.log.error( self.name + ": counterTestAddAndGet did not" +
Jon Hall390696c2015-05-05 17:13:41 -07004432 " match expected output." )
4433 main.log.debug( self.name + " expected: " + pattern )
4434 main.log.debug( self.name + " actual: " + repr( output ) )
4435 return None
Jon Hall390696c2015-05-05 17:13:41 -07004436 except TypeError:
4437 main.log.exception( self.name + ": Object not as expected" )
4438 return None
Jon Hall390696c2015-05-05 17:13:41 -07004439 except Exception:
4440 main.log.exception( self.name + ": Uncaught exception!" )
4441 main.cleanup()
4442 main.exit()
4443
Jon Hall935db192016-04-19 00:22:04 -07004444 def counterTestGetAndAdd( self, counter, delta=1 ):
Jon Halle1a3b752015-07-22 13:02:46 -07004445 """
4446 CLI command to get a distributed counter then add a delta to it.
4447 Required arguments:
4448 counter - The name of the counter to increment.
4449 Optional arguments:
4450 delta - The long to add to the counter
Jon Halle1a3b752015-07-22 13:02:46 -07004451 returns:
4452 integer value of the counter or
4453 None on Error
4454 """
4455 try:
4456 counter = str( counter )
4457 delta = int( delta )
4458 cmdStr = "counter-test-increment -g "
Jon Halle1a3b752015-07-22 13:02:46 -07004459 cmdStr += counter
4460 if delta != 1:
4461 cmdStr += " " + str( delta )
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004462 output = self.distPrimitivesSend( cmdStr )
Jon Halle1a3b752015-07-22 13:02:46 -07004463 pattern = counter + " was updated to (-?\d+)"
4464 match = re.search( pattern, output )
4465 if match:
4466 return int( match.group( 1 ) )
4467 else:
4468 main.log.error( self.name + ": counterTestGetAndAdd did not" +
4469 " match expected output." )
4470 main.log.debug( self.name + " expected: " + pattern )
4471 main.log.debug( self.name + " actual: " + repr( output ) )
4472 return None
Jon Halle1a3b752015-07-22 13:02:46 -07004473 except TypeError:
4474 main.log.exception( self.name + ": Object not as expected" )
4475 return None
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004476 except Exception:
4477 main.log.exception( self.name + ": Uncaught exception!" )
Jon Halle1a3b752015-07-22 13:02:46 -07004478 main.cleanup()
4479 main.exit()
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004480
4481 def valueTestGet( self, valueName ):
4482 """
4483 CLI command to get the value of an atomic value.
4484 Required arguments:
4485 valueName - The name of the value to get.
4486 returns:
4487 string value of the value or
4488 None on Error
4489 """
4490 try:
4491 valueName = str( valueName )
4492 cmdStr = "value-test "
4493 operation = "get"
4494 cmdStr = "value-test {} {}".format( valueName,
4495 operation )
4496 output = self.distPrimitivesSend( cmdStr )
4497 pattern = "(\w+)"
4498 match = re.search( pattern, output )
4499 if match:
4500 return match.group( 1 )
4501 else:
4502 main.log.error( self.name + ": valueTestGet did not" +
4503 " match expected output." )
4504 main.log.debug( self.name + " expected: " + pattern )
4505 main.log.debug( self.name + " actual: " + repr( output ) )
4506 return None
4507 except TypeError:
4508 main.log.exception( self.name + ": Object not as expected" )
4509 return None
4510 except Exception:
4511 main.log.exception( self.name + ": Uncaught exception!" )
4512 main.cleanup()
4513 main.exit()
4514
4515 def valueTestSet( self, valueName, newValue ):
4516 """
4517 CLI command to set the value of an atomic value.
4518 Required arguments:
4519 valueName - The name of the value to set.
4520 newValue - The value to assign to the given value.
4521 returns:
4522 main.TRUE on success or
4523 main.ERROR on Error
4524 """
4525 try:
4526 valueName = str( valueName )
4527 newValue = str( newValue )
4528 operation = "set"
4529 cmdStr = "value-test {} {} {}".format( valueName,
4530 operation,
4531 newValue )
4532 output = self.distPrimitivesSend( cmdStr )
4533 if output is not None:
4534 return main.TRUE
4535 else:
4536 return main.ERROR
4537 except TypeError:
4538 main.log.exception( self.name + ": Object not as expected" )
4539 return main.ERROR
4540 except Exception:
4541 main.log.exception( self.name + ": Uncaught exception!" )
4542 main.cleanup()
4543 main.exit()
4544
4545 def valueTestCompareAndSet( self, valueName, oldValue, newValue ):
4546 """
4547 CLI command to compareAndSet the value of an atomic value.
4548 Required arguments:
4549 valueName - The name of the value.
4550 oldValue - Compare the current value of the atomic value to this
4551 newValue - If the value equals oldValue, set the value to newValue
4552 returns:
4553 main.TRUE on success or
4554 main.FALSE on failure or
4555 main.ERROR on Error
4556 """
4557 try:
4558 valueName = str( valueName )
4559 oldValue = str( oldValue )
4560 newValue = str( newValue )
4561 operation = "compareAndSet"
4562 cmdStr = "value-test {} {} {} {}".format( valueName,
4563 operation,
4564 oldValue,
4565 newValue )
4566 output = self.distPrimitivesSend( cmdStr )
4567 pattern = "(\w+)"
4568 match = re.search( pattern, output )
4569 if match:
4570 result = match.group( 1 )
4571 if result == "true":
4572 return main.TRUE
4573 elif result == "false":
4574 return main.FALSE
4575 else:
4576 main.log.error( self.name + ": valueTestCompareAndSet did not" +
4577 " match expected output." )
4578 main.log.debug( self.name + " expected: " + pattern )
4579 main.log.debug( self.name + " actual: " + repr( output ) )
4580 return main.ERROR
4581 except TypeError:
4582 main.log.exception( self.name + ": Object not as expected" )
4583 return main.ERROR
4584 except Exception:
4585 main.log.exception( self.name + ": Uncaught exception!" )
4586 main.cleanup()
4587 main.exit()
4588
4589 def valueTestGetAndSet( self, valueName, newValue ):
4590 """
4591 CLI command to getAndSet the value of an atomic value.
4592 Required arguments:
4593 valueName - The name of the value to get.
4594 newValue - The value to assign to the given value
4595 returns:
4596 string value of the value or
4597 None on Error
4598 """
4599 try:
4600 valueName = str( valueName )
4601 cmdStr = "value-test "
4602 operation = "getAndSet"
4603 cmdStr += valueName + " " + operation
4604 cmdStr = "value-test {} {} {}".format( valueName,
4605 operation,
4606 newValue )
4607 output = self.distPrimitivesSend( cmdStr )
4608 pattern = "(\w+)"
4609 match = re.search( pattern, output )
4610 if match:
4611 return match.group( 1 )
4612 else:
4613 main.log.error( self.name + ": valueTestGetAndSet did not" +
4614 " match expected output." )
4615 main.log.debug( self.name + " expected: " + pattern )
4616 main.log.debug( self.name + " actual: " + repr( output ) )
4617 return None
4618 except TypeError:
4619 main.log.exception( self.name + ": Object not as expected" )
4620 return None
4621 except Exception:
4622 main.log.exception( self.name + ": Uncaught exception!" )
4623 main.cleanup()
4624 main.exit()
4625
4626 def valueTestDestroy( self, valueName ):
4627 """
4628 CLI command to destroy an atomic value.
4629 Required arguments:
4630 valueName - The name of the value to destroy.
4631 returns:
4632 main.TRUE on success or
4633 main.ERROR on Error
4634 """
4635 try:
4636 valueName = str( valueName )
4637 cmdStr = "value-test "
4638 operation = "destroy"
4639 cmdStr += valueName + " " + operation
4640 output = self.distPrimitivesSend( cmdStr )
4641 if output is not None:
4642 return main.TRUE
4643 else:
4644 return main.ERROR
4645 except TypeError:
4646 main.log.exception( self.name + ": Object not as expected" )
4647 return main.ERROR
Jon Halle1a3b752015-07-22 13:02:46 -07004648 except Exception:
4649 main.log.exception( self.name + ": Uncaught exception!" )
4650 main.cleanup()
4651 main.exit()
4652
YPZhangfebf7302016-05-24 16:45:56 -07004653 def summary( self, jsonFormat=True, timeout=30 ):
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004654 """
4655 Description: Execute summary command in onos
4656 Returns: json object ( summary -j ), returns main.FALSE if there is
4657 no output
4658
4659 """
4660 try:
4661 cmdStr = "summary"
4662 if jsonFormat:
4663 cmdStr += " -j"
YPZhangfebf7302016-05-24 16:45:56 -07004664 handle = self.sendline( cmdStr, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07004665 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004666 assert "Command not found:" not in handle, handle
Jon Hall6e709752016-02-01 13:38:46 -08004667 assert "Error:" not in handle, handle
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004668 if not handle:
4669 main.log.error( self.name + ": There is no output in " +
4670 "summary command" )
4671 return main.FALSE
4672 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004673 except AssertionError:
Jon Hall6e709752016-02-01 13:38:46 -08004674 main.log.exception( "{} Error in summary output:".format( self.name ) )
Jon Hallc6793552016-01-19 14:18:37 -08004675 return None
kelvin-onlaba297c4d2015-06-01 13:53:55 -07004676 except TypeError:
4677 main.log.exception( self.name + ": Object not as expected" )
4678 return None
4679 except pexpect.EOF:
4680 main.log.error( self.name + ": EOF exception found" )
4681 main.log.error( self.name + ": " + self.handle.before )
4682 main.cleanup()
4683 main.exit()
4684 except Exception:
4685 main.log.exception( self.name + ": Uncaught exception!" )
4686 main.cleanup()
4687 main.exit()
Jon Hall2a5002c2015-08-21 16:49:11 -07004688
Jon Hall935db192016-04-19 00:22:04 -07004689 def transactionalMapGet( self, keyName ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004690 """
4691 CLI command to get the value of a key in a consistent map using
4692 transactions. This a test function and can only get keys from the
4693 test map hard coded into the cli command
4694 Required arguments:
4695 keyName - The name of the key to get
Jon Hall2a5002c2015-08-21 16:49:11 -07004696 returns:
4697 The string value of the key or
4698 None on Error
4699 """
4700 try:
4701 keyName = str( keyName )
4702 cmdStr = "transactional-map-test-get "
Jon Hall2a5002c2015-08-21 16:49:11 -07004703 cmdStr += keyName
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004704 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004705 pattern = "Key-value pair \(" + keyName + ", (?P<value>.+)\) found."
4706 if "Key " + keyName + " not found." in output:
Jon Hall9bfadd22016-05-11 14:48:07 -07004707 main.log.warn( output )
Jon Hall2a5002c2015-08-21 16:49:11 -07004708 return None
4709 else:
4710 match = re.search( pattern, output )
4711 if match:
4712 return match.groupdict()[ 'value' ]
4713 else:
4714 main.log.error( self.name + ": transactionlMapGet did not" +
4715 " match expected output." )
4716 main.log.debug( self.name + " expected: " + pattern )
4717 main.log.debug( self.name + " actual: " + repr( output ) )
4718 return None
4719 except TypeError:
4720 main.log.exception( self.name + ": Object not as expected" )
4721 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004722 except Exception:
4723 main.log.exception( self.name + ": Uncaught exception!" )
4724 main.cleanup()
4725 main.exit()
4726
Jon Hall935db192016-04-19 00:22:04 -07004727 def transactionalMapPut( self, numKeys, value ):
Jon Hall2a5002c2015-08-21 16:49:11 -07004728 """
4729 CLI command to put a value into 'numKeys' number of keys in a
4730 consistent map using transactions. This a test function and can only
4731 put into keys named 'Key#' of the test map hard coded into the cli command
4732 Required arguments:
4733 numKeys - Number of keys to add the value to
4734 value - The string value to put into the keys
Jon Hall2a5002c2015-08-21 16:49:11 -07004735 returns:
4736 A dictionary whose keys are the name of the keys put into the map
4737 and the values of the keys are dictionaries whose key-values are
4738 'value': value put into map and optionaly
4739 'oldValue': Previous value in the key or
4740 None on Error
4741
4742 Example output
4743 { 'Key1': {'oldValue': 'oldTestValue', 'value': 'Testing'},
4744 'Key2': {'value': 'Testing'} }
4745 """
4746 try:
4747 numKeys = str( numKeys )
4748 value = str( value )
4749 cmdStr = "transactional-map-test-put "
Jon Hall2a5002c2015-08-21 16:49:11 -07004750 cmdStr += numKeys + " " + value
Jon Hall7a6ebfd2017-03-13 10:58:58 -07004751 output = self.distPrimitivesSend( cmdStr )
Jon Hall2a5002c2015-08-21 16:49:11 -07004752 newPattern = 'Created Key (?P<key>(\w)+) with value (?P<value>(.)+)\.'
4753 updatedPattern = "Put (?P<value>(.)+) into key (?P<key>(\w)+)\. The old value was (?P<oldValue>(.)+)\."
4754 results = {}
4755 for line in output.splitlines():
4756 new = re.search( newPattern, line )
4757 updated = re.search( updatedPattern, line )
4758 if new:
4759 results[ new.groupdict()[ 'key' ] ] = { 'value': new.groupdict()[ 'value' ] }
4760 elif updated:
4761 results[ updated.groupdict()[ 'key' ] ] = { 'value': updated.groupdict()[ 'value' ],
Jon Hallc6793552016-01-19 14:18:37 -08004762 'oldValue': updated.groupdict()[ 'oldValue' ] }
Jon Hall2a5002c2015-08-21 16:49:11 -07004763 else:
4764 main.log.error( self.name + ": transactionlMapGet did not" +
4765 " match expected output." )
Jon Hallc6793552016-01-19 14:18:37 -08004766 main.log.debug( "{} expected: {!r} or {!r}".format( self.name,
4767 newPattern,
4768 updatedPattern ) )
Jon Hall2a5002c2015-08-21 16:49:11 -07004769 main.log.debug( self.name + " actual: " + repr( output ) )
4770 return results
4771 except TypeError:
4772 main.log.exception( self.name + ": Object not as expected" )
4773 return None
Jon Hall2a5002c2015-08-21 16:49:11 -07004774 except Exception:
4775 main.log.exception( self.name + ": Uncaught exception!" )
4776 main.cleanup()
4777 main.exit()
Jon Hallc6793552016-01-19 14:18:37 -08004778
acsmarsdaea66c2015-09-03 11:44:06 -07004779 def maps( self, jsonFormat=True ):
4780 """
4781 Description: Returns result of onos:maps
4782 Optional:
4783 * jsonFormat: enable json formatting of output
4784 """
4785 try:
4786 cmdStr = "maps"
4787 if jsonFormat:
4788 cmdStr += " -j"
4789 handle = self.sendline( cmdStr )
Jon Halla495f562016-05-16 18:03:26 -07004790 assert handle is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004791 assert "Command not found:" not in handle, handle
acsmarsdaea66c2015-09-03 11:44:06 -07004792 return handle
Jon Hallc6793552016-01-19 14:18:37 -08004793 except AssertionError:
4794 main.log.exception( "" )
4795 return None
acsmarsdaea66c2015-09-03 11:44:06 -07004796 except TypeError:
4797 main.log.exception( self.name + ": Object not as expected" )
4798 return None
4799 except pexpect.EOF:
4800 main.log.error( self.name + ": EOF exception found" )
4801 main.log.error( self.name + ": " + self.handle.before )
4802 main.cleanup()
4803 main.exit()
4804 except Exception:
4805 main.log.exception( self.name + ": Uncaught exception!" )
4806 main.cleanup()
4807 main.exit()
GlennRC050596c2015-11-18 17:06:41 -08004808
4809 def getSwController( self, uri, jsonFormat=True ):
4810 """
4811 Descrition: Gets the controller information from the device
4812 """
4813 try:
4814 cmd = "device-controllers "
4815 if jsonFormat:
4816 cmd += "-j "
4817 response = self.sendline( cmd + uri )
Jon Halla495f562016-05-16 18:03:26 -07004818 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004819 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004820 return response
Jon Hallc6793552016-01-19 14:18:37 -08004821 except AssertionError:
4822 main.log.exception( "" )
4823 return None
GlennRC050596c2015-11-18 17:06:41 -08004824 except TypeError:
4825 main.log.exception( self.name + ": Object not as expected" )
4826 return None
4827 except pexpect.EOF:
4828 main.log.error( self.name + ": EOF exception found" )
4829 main.log.error( self.name + ": " + self.handle.before )
4830 main.cleanup()
4831 main.exit()
4832 except Exception:
4833 main.log.exception( self.name + ": Uncaught exception!" )
4834 main.cleanup()
4835 main.exit()
4836
4837 def setSwController( self, uri, ip, proto="tcp", port="6653", jsonFormat=True ):
4838 """
4839 Descrition: sets the controller(s) for the specified device
4840
4841 Parameters:
4842 Required: uri - String: The uri of the device(switch).
4843 ip - String or List: The ip address of the controller.
4844 This parameter can be formed in a couple of different ways.
4845 VALID:
4846 10.0.0.1 - just the ip address
4847 tcp:10.0.0.1 - the protocol and the ip address
4848 tcp:10.0.0.1:6653 - the protocol and port can be specified,
4849 so that you can add controllers with different
4850 protocols and ports
4851 INVALID:
4852 10.0.0.1:6653 - this is not supported by ONOS
4853
4854 Optional: proto - The type of connection e.g. tcp, ssl. If a list of ips are given
4855 port - The port number.
4856 jsonFormat - If set ONOS will output in json NOTE: This is currently not supported
4857
4858 Returns: main.TRUE if ONOS returns without any errors, otherwise returns main.FALSE
4859 """
4860 try:
4861 cmd = "device-setcontrollers"
4862
4863 if jsonFormat:
4864 cmd += " -j"
4865 cmd += " " + uri
4866 if isinstance( ip, str ):
4867 ip = [ip]
4868 for item in ip:
4869 if ":" in item:
4870 sitem = item.split( ":" )
4871 if len(sitem) == 3:
4872 cmd += " " + item
4873 elif "." in sitem[1]:
4874 cmd += " {}:{}".format(item, port)
4875 else:
4876 main.log.error( "Malformed entry: " + item )
4877 raise TypeError
4878 else:
4879 cmd += " {}:{}:{}".format( proto, item, port )
GlennRC050596c2015-11-18 17:06:41 -08004880 response = self.sendline( cmd )
Jon Halla495f562016-05-16 18:03:26 -07004881 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004882 assert "Command not found:" not in response, response
GlennRC050596c2015-11-18 17:06:41 -08004883 if "Error" in response:
4884 main.log.error( response )
4885 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004886 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004887 except AssertionError:
4888 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004889 return main.FALSE
GlennRC050596c2015-11-18 17:06:41 -08004890 except TypeError:
4891 main.log.exception( self.name + ": Object not as expected" )
4892 return main.FALSE
4893 except pexpect.EOF:
4894 main.log.error( self.name + ": EOF exception found" )
4895 main.log.error( self.name + ": " + self.handle.before )
4896 main.cleanup()
4897 main.exit()
4898 except Exception:
4899 main.log.exception( self.name + ": Uncaught exception!" )
4900 main.cleanup()
4901 main.exit()
GlennRC20fc6522015-12-23 23:26:57 -08004902
4903 def removeDevice( self, device ):
4904 '''
4905 Description:
4906 Remove a device from ONOS by passing the uri of the device(s).
4907 Parameters:
4908 device - (str or list) the id or uri of the device ex. "of:0000000000000001"
4909 Returns:
4910 Returns main.FALSE if an exception is thrown or an error is present
4911 in the response. Otherwise, returns main.TRUE.
4912 NOTE:
4913 If a host cannot be removed, then this function will return main.FALSE
4914 '''
4915 try:
4916 if type( device ) is str:
You Wang823f5022016-08-18 15:24:41 -07004917 deviceStr = device
4918 device = []
4919 device.append( deviceStr )
GlennRC20fc6522015-12-23 23:26:57 -08004920
4921 for d in device:
4922 time.sleep( 1 )
4923 response = self.sendline( "device-remove {}".format( d ) )
Jon Halla495f562016-05-16 18:03:26 -07004924 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004925 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004926 if "Error" in response:
4927 main.log.warn( "Error for device: {}\nResponse: {}".format( d, response ) )
4928 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004929 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004930 except AssertionError:
4931 main.log.exception( "" )
4932 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004933 except TypeError:
4934 main.log.exception( self.name + ": Object not as expected" )
4935 return main.FALSE
4936 except pexpect.EOF:
4937 main.log.error( self.name + ": EOF exception found" )
4938 main.log.error( self.name + ": " + self.handle.before )
4939 main.cleanup()
4940 main.exit()
4941 except Exception:
4942 main.log.exception( self.name + ": Uncaught exception!" )
4943 main.cleanup()
4944 main.exit()
4945
4946 def removeHost( self, host ):
4947 '''
4948 Description:
4949 Remove a host from ONOS by passing the id of the host(s)
4950 Parameters:
4951 hostId - (str or list) the id or mac of the host ex. "00:00:00:00:00:01"
4952 Returns:
4953 Returns main.FALSE if an exception is thrown or an error is present
4954 in the response. Otherwise, returns main.TRUE.
4955 NOTE:
4956 If a host cannot be removed, then this function will return main.FALSE
4957 '''
4958 try:
4959 if type( host ) is str:
4960 host = list( host )
4961
4962 for h in host:
4963 time.sleep( 1 )
4964 response = self.sendline( "host-remove {}".format( h ) )
Jon Halla495f562016-05-16 18:03:26 -07004965 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08004966 assert "Command not found:" not in response, response
GlennRC20fc6522015-12-23 23:26:57 -08004967 if "Error" in response:
4968 main.log.warn( "Error for host: {}\nResponse: {}".format( h, response ) )
4969 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004970 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08004971 except AssertionError:
4972 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08004973 return main.FALSE
GlennRC20fc6522015-12-23 23:26:57 -08004974 except TypeError:
4975 main.log.exception( self.name + ": Object not as expected" )
4976 return main.FALSE
4977 except pexpect.EOF:
4978 main.log.error( self.name + ": EOF exception found" )
4979 main.log.error( self.name + ": " + self.handle.before )
4980 main.cleanup()
4981 main.exit()
4982 except Exception:
4983 main.log.exception( self.name + ": Uncaught exception!" )
4984 main.cleanup()
4985 main.exit()
GlennRCed771242016-01-13 17:02:47 -08004986
YPZhangfebf7302016-05-24 16:45:56 -07004987 def link( self, begin, end, state, timeout=30, showResponse=True ):
GlennRCed771242016-01-13 17:02:47 -08004988 '''
4989 Description:
4990 Bring link down or up in the null-provider.
4991 params:
4992 begin - (string) One end of a device or switch.
4993 end - (string) the other end of the device or switch
4994 returns:
4995 main.TRUE if no exceptions were thrown and no Errors are
4996 present in the resoponse. Otherwise, returns main.FALSE
4997 '''
4998 try:
Jon Halle0f0b342017-04-18 11:43:47 -07004999 cmd = "null-link null:{} null:{} {}".format( begin, end, state )
YPZhangfebf7302016-05-24 16:45:56 -07005000 response = self.sendline( cmd, showResponse=showResponse, timeout=timeout )
Jon Halla495f562016-05-16 18:03:26 -07005001 assert response is not None, "Error in sendline"
Jon Hallc6793552016-01-19 14:18:37 -08005002 assert "Command not found:" not in response, response
GlennRCed771242016-01-13 17:02:47 -08005003 if "Error" in response or "Failure" in response:
5004 main.log.error( response )
5005 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005006 return main.TRUE
Jon Hallc6793552016-01-19 14:18:37 -08005007 except AssertionError:
5008 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005009 return main.FALSE
GlennRCed771242016-01-13 17:02:47 -08005010 except TypeError:
5011 main.log.exception( self.name + ": Object not as expected" )
5012 return main.FALSE
5013 except pexpect.EOF:
5014 main.log.error( self.name + ": EOF exception found" )
5015 main.log.error( self.name + ": " + self.handle.before )
5016 main.cleanup()
5017 main.exit()
5018 except Exception:
5019 main.log.exception( self.name + ": Uncaught exception!" )
5020 main.cleanup()
5021 main.exit()
5022
Jon Hall2c8959e2016-12-16 12:17:34 -08005023 def portstate( self, dpid, port, state ):
Flavio Castro82ee2f62016-06-07 15:04:12 -07005024 '''
5025 Description:
5026 Changes the state of port in an OF switch by means of the
5027 PORTSTATUS OF messages.
5028 params:
Jon Hall2c8959e2016-12-16 12:17:34 -08005029 dpid - (string) Datapath ID of the device. Ex: 'of:0000000000000102'
5030 port - (string) target port in the device. Ex: '2'
5031 state - (string) target state (enable or disable)
Flavio Castro82ee2f62016-06-07 15:04:12 -07005032 returns:
5033 main.TRUE if no exceptions were thrown and no Errors are
5034 present in the resoponse. Otherwise, returns main.FALSE
5035 '''
5036 try:
Jon Hall2c8959e2016-12-16 12:17:34 -08005037 state = state.lower()
5038 assert state == 'enable' or state == 'disable', "Unknown state"
Jon Halle0f0b342017-04-18 11:43:47 -07005039 cmd = "portstate {} {} {}".format( dpid, port, state )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005040 response = self.sendline( cmd, showResponse=True )
5041 assert response is not None, "Error in sendline"
5042 assert "Command not found:" not in response, response
5043 if "Error" in response or "Failure" in response:
5044 main.log.error( response )
5045 return main.FALSE
5046 return main.TRUE
5047 except AssertionError:
5048 main.log.exception( "" )
Jon Hall2c8959e2016-12-16 12:17:34 -08005049 return main.FALSE
Flavio Castro82ee2f62016-06-07 15:04:12 -07005050 except TypeError:
5051 main.log.exception( self.name + ": Object not as expected" )
5052 return main.FALSE
5053 except pexpect.EOF:
5054 main.log.error( self.name + ": EOF exception found" )
5055 main.log.error( self.name + ": " + self.handle.before )
5056 main.cleanup()
5057 main.exit()
5058 except Exception:
5059 main.log.exception( self.name + ": Uncaught exception!" )
5060 main.cleanup()
5061 main.exit()
5062
5063 def logSet( self, level="INFO", app="org.onosproject" ):
5064 """
5065 Set the logging level to lvl for a specific app
5066 returns main.TRUE on success
5067 returns main.FALSE if Error occurred
5068 if noExit is True, TestON will not exit, but clean up
5069 Available level: DEBUG, TRACE, INFO, WARN, ERROR
5070 Level defaults to INFO
5071 """
5072 try:
Jon Halle0f0b342017-04-18 11:43:47 -07005073 self.handle.sendline( "log:set %s %s" % ( level, app ) )
Flavio Castro82ee2f62016-06-07 15:04:12 -07005074 self.handle.expect( "onos>" )
5075
5076 response = self.handle.before
5077 if re.search( "Error", response ):
5078 return main.FALSE
5079 return main.TRUE
5080 except pexpect.TIMEOUT:
5081 main.log.exception( self.name + ": TIMEOUT exception found" )
5082 main.cleanup()
5083 main.exit()
5084 except pexpect.EOF:
5085 main.log.error( self.name + ": EOF exception found" )
5086 main.log.error( self.name + ": " + self.handle.before )
5087 main.cleanup()
5088 main.exit()
5089 except Exception:
5090 main.log.exception( self.name + ": Uncaught exception!" )
5091 main.cleanup()
5092 main.exit()
You Wangdb8cd0a2016-05-26 15:19:45 -07005093
5094 def getGraphDict( self, timeout=60, includeHost=False ):
5095 """
5096 Return a dictionary which describes the latest network topology data as a
5097 graph.
5098 An example of the dictionary:
5099 { vertex1: { 'edges': ..., 'name': ..., 'protocol': ... },
5100 vertex2: { 'edges': ..., 'name': ..., 'protocol': ... } }
5101 Each vertex should at least have an 'edges' attribute which describes the
5102 adjacency information. The value of 'edges' attribute is also represented by
5103 a dictionary, which maps each edge (identified by the neighbor vertex) to a
5104 list of attributes.
5105 An example of the edges dictionary:
5106 'edges': { vertex2: { 'port': ..., 'weight': ... },
5107 vertex3: { 'port': ..., 'weight': ... } }
5108 If includeHost == True, all hosts (and host-switch links) will be included
5109 in topology data.
5110 """
5111 graphDict = {}
5112 try:
5113 links = self.links()
5114 links = json.loads( links )
5115 devices = self.devices()
5116 devices = json.loads( devices )
5117 idToDevice = {}
5118 for device in devices:
5119 idToDevice[ device[ 'id' ] ] = device
5120 if includeHost:
5121 hosts = self.hosts()
5122 # FIXME: support 'includeHost' argument
5123 for link in links:
5124 nodeA = link[ 'src' ][ 'device' ]
5125 nodeB = link[ 'dst' ][ 'device' ]
5126 assert idToDevice[ nodeA ][ 'available' ] and idToDevice[ nodeB ][ 'available' ]
Jon Halle0f0b342017-04-18 11:43:47 -07005127 if nodeA not in graphDict.keys():
5128 graphDict[ nodeA ] = { 'edges': {},
5129 'dpid': idToDevice[ nodeA ][ 'id' ][3:],
5130 'type': idToDevice[ nodeA ][ 'type' ],
5131 'available': idToDevice[ nodeA ][ 'available' ],
5132 'role': idToDevice[ nodeA ][ 'role' ],
5133 'mfr': idToDevice[ nodeA ][ 'mfr' ],
5134 'hw': idToDevice[ nodeA ][ 'hw' ],
5135 'sw': idToDevice[ nodeA ][ 'sw' ],
5136 'serial': idToDevice[ nodeA ][ 'serial' ],
5137 'chassisId': idToDevice[ nodeA ][ 'chassisId' ],
5138 'annotations': idToDevice[ nodeA ][ 'annotations' ]}
You Wangdb8cd0a2016-05-26 15:19:45 -07005139 else:
5140 # Assert nodeB is not connected to any current links of nodeA
5141 assert nodeB not in graphDict[ nodeA ][ 'edges' ].keys()
Jon Halle0f0b342017-04-18 11:43:47 -07005142 graphDict[ nodeA ][ 'edges' ][ nodeB ] = { 'port': link[ 'src' ][ 'port' ],
5143 'type': link[ 'type' ],
5144 'state': link[ 'state' ] }
You Wangdb8cd0a2016-05-26 15:19:45 -07005145 return graphDict
5146 except ( TypeError, ValueError ):
5147 main.log.exception( self.name + ": Object not as expected" )
5148 return None
5149 except KeyError:
5150 main.log.exception( self.name + ": KeyError exception found" )
5151 return None
5152 except AssertionError:
5153 main.log.exception( self.name + ": AssertionError exception found" )
5154 return None
5155 except pexpect.EOF:
5156 main.log.error( self.name + ": EOF exception found" )
5157 main.log.error( self.name + ": " + self.handle.before )
5158 return None
5159 except Exception:
5160 main.log.exception( self.name + ": Uncaught exception!" )
5161 return None
YPZhangcbc2a062016-07-11 10:55:44 -07005162
5163 def getIntentPerfSummary( self ):
5164 '''
5165 Send command to check intent-perf summary
5166 Returns: dictionary for intent-perf summary
5167 if something wrong, function will return None
5168 '''
5169 cmd = "intent-perf -s"
5170 respDic = {}
5171 resp = self.sendline( cmd )
You Wangb5a55f72017-03-03 12:51:05 -08005172 assert resp is not None, "Error in sendline"
5173 assert "Command not found:" not in resp, resp
YPZhangcbc2a062016-07-11 10:55:44 -07005174 try:
5175 # Generate the dictionary to return
5176 for l in resp.split( "\n" ):
5177 # Delete any white space in line
5178 temp = re.sub( r'\s+', '', l )
5179 temp = temp.split( ":" )
5180 respDic[ temp[0] ] = temp[ 1 ]
5181
5182 except (TypeError, ValueError):
5183 main.log.exception( self.name + ": Object not as expected" )
5184 return None
5185 except KeyError:
5186 main.log.exception( self.name + ": KeyError exception found" )
5187 return None
5188 except AssertionError:
5189 main.log.exception( self.name + ": AssertionError exception found" )
5190 return None
5191 except pexpect.EOF:
5192 main.log.error( self.name + ": EOF exception found" )
5193 main.log.error( self.name + ": " + self.handle.before )
5194 return None
5195 except Exception:
5196 main.log.exception( self.name + ": Uncaught exception!" )
5197 return None
5198 return respDic
5199
Chiyu Chengec63bde2016-11-17 18:11:36 -08005200 def logSearch( self, mode='all', searchTerm='', startLine='', logNum=1 ):
chengchiyu08303a02016-09-08 17:40:26 -07005201 """
5202 Searches the latest ONOS log file for the given search term and
5203 return a list that contains all the lines that have the search term.
YPZhangcbc2a062016-07-11 10:55:44 -07005204
chengchiyu08303a02016-09-08 17:40:26 -07005205 Arguments:
Chiyu Chengec63bde2016-11-17 18:11:36 -08005206 searchTerm:
5207 The string to grep from the ONOS log.
5208 startLine:
5209 The term that decides which line is the start to search the searchTerm in
5210 the karaf log. For now, startTerm only works in 'first' mode.
5211 logNum:
5212 In some extreme cases, one karaf log is not big enough to contain all the
5213 information.Because of this, search mutiply logs is necessary to capture
5214 the right result. logNum is the number of karaf logs that we need to search
5215 the searchTerm.
chengchiyu08303a02016-09-08 17:40:26 -07005216 mode:
5217 all: return all the strings that contain the search term
5218 last: return the last string that contains the search term
5219 first: return the first string that contains the search term
Chiyu Chengec63bde2016-11-17 18:11:36 -08005220 num: return the number of times that the searchTerm appears in the log
5221 total: return how many lines in karaf log
chengchiyu08303a02016-09-08 17:40:26 -07005222 """
5223 try:
5224 assert type( searchTerm ) is str
Jon Halle0f0b342017-04-18 11:43:47 -07005225 # Build the log paths string
Chiyu Chengec63bde2016-11-17 18:11:36 -08005226 logPath = '/opt/onos/log/karaf.log.'
5227 logPaths = '/opt/onos/log/karaf.log'
5228 for i in range( 1, logNum ):
5229 logPaths = logPath + str( i ) + " " + logPaths
5230 cmd = "cat " + logPaths
You Wang6d301d42017-04-21 10:49:33 -07005231 if startLine:
5232 # 100000000 is just a extreme large number to make sure this function can grep all the lines after startLine
5233 cmd = cmd + " | grep -A 100000000 \'" + startLine + "\'"
Chiyu Chengec63bde2016-11-17 18:11:36 -08005234 if mode == 'all':
5235 cmd = cmd + " | grep \'" + searchTerm + "\'"
You Wang6d301d42017-04-21 10:49:33 -07005236 elif mode == 'last':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005237 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | tail -n 1"
You Wang6d301d42017-04-21 10:49:33 -07005238 elif mode == 'first':
5239 cmd = cmd + " | grep \'" + searchTerm + "\'" + " | head -n 1"
5240 elif mode == 'num':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005241 cmd = cmd + " | grep -c \'" + searchTerm + "\'"
You Wang118ba582017-01-02 17:14:43 -08005242 num = self.sendline( cmd )
Chiyu Chengb8c2c842016-10-05 12:40:49 -07005243 return num
You Wang6d301d42017-04-21 10:49:33 -07005244 elif mode == 'total':
Chiyu Chengec63bde2016-11-17 18:11:36 -08005245 totalLines = self.sendline( "cat /opt/onos/log/karaf.log | wc -l" )
5246 return int(totalLines)
You Wang6d301d42017-04-21 10:49:33 -07005247 else:
5248 main.log.error( self.name + " unsupported mode" )
5249 return main.ERROR
chengchiyu08303a02016-09-08 17:40:26 -07005250 before = self.sendline( cmd )
5251 before = before.splitlines()
5252 # make sure the returned list only contains the search term
5253 returnLines = [line for line in before if searchTerm in line]
5254 return returnLines
5255 except AssertionError:
5256 main.log.error( self.name + " searchTerm is not string type" )
5257 return None
5258 except pexpect.EOF:
5259 main.log.error( self.name + ": EOF exception found" )
5260 main.log.error( self.name + ": " + self.handle.before )
5261 main.cleanup()
5262 main.exit()
5263 except pexpect.TIMEOUT:
5264 main.log.error( self.name + ": TIMEOUT exception found" )
5265 main.log.error( self.name + ": " + self.handle.before )
5266 main.cleanup()
5267 main.exit()
5268 except Exception:
5269 main.log.exception( self.name + ": Uncaught exception!" )
5270 main.cleanup()
5271 main.exit()
Jon Hall2c8959e2016-12-16 12:17:34 -08005272
5273 def vplsShow( self, jsonFormat=True ):
5274 """
5275 Description: Returns result of onos:vpls show, which should list the
5276 configured VPLS networks and the assigned interfaces.
5277 Optional:
5278 * jsonFormat: enable json formatting of output
5279 Returns:
5280 The output of the command or None on error.
5281 """
5282 try:
5283 cmdStr = "vpls show"
5284 if jsonFormat:
5285 raise NotImplementedError
5286 cmdStr += " -j"
5287 handle = self.sendline( cmdStr )
5288 assert handle is not None, "Error in sendline"
5289 assert "Command not found:" not in handle, handle
5290 return handle
5291 except AssertionError:
5292 main.log.exception( "" )
5293 return None
5294 except TypeError:
5295 main.log.exception( self.name + ": Object not as expected" )
5296 return None
5297 except pexpect.EOF:
5298 main.log.error( self.name + ": EOF exception found" )
5299 main.log.error( self.name + ": " + self.handle.before )
5300 main.cleanup()
5301 main.exit()
5302 except NotImplementedError:
5303 main.log.exception( self.name + ": Json output not supported")
5304 return None
5305 except Exception:
5306 main.log.exception( self.name + ": Uncaught exception!" )
5307 main.cleanup()
5308 main.exit()
5309
5310 def parseVplsShow( self ):
5311 """
5312 Parse the cli output of 'vpls show' into json output. This is required
5313 as there is currently no json output available.
5314 """
5315 try:
5316 output = []
5317 raw = self.vplsShow( jsonFormat=False )
5318 namePat = "VPLS name: (?P<name>\w+)"
5319 interfacesPat = "Associated interfaces: \[(?P<interfaces>.*)\]"
5320 encapPat = "Encapsulation: (?P<encap>\w+)"
5321 pattern = "\s+".join( [ namePat, interfacesPat, encapPat ] )
5322 mIter = re.finditer( pattern, raw )
5323 for match in mIter:
5324 item = {}
5325 item[ 'name' ] = match.group( 'name' )
5326 ifaces = match.group( 'interfaces' ).split( ', ')
5327 if ifaces == [ "" ]:
5328 ifaces = []
5329 item[ 'interfaces' ] = ifaces
5330 encap = match.group( 'encap' )
5331 if encap != 'NONE':
5332 item[ 'encapsulation' ] = encap.lower()
5333 output.append( item )
5334 return output
5335 except Exception:
5336 main.log.exception( self.name + ": Uncaught exception!" )
5337 main.cleanup()
5338 main.exit()
5339
5340 def vplsList( self, jsonFormat=True ):
5341 """
5342 Description: Returns result of onos:vpls list, which should list the
5343 configured VPLS networks.
5344 Optional:
5345 * jsonFormat: enable json formatting of output
5346 """
5347 try:
5348 cmdStr = "vpls list"
5349 if jsonFormat:
5350 raise NotImplementedError
5351 cmdStr += " -j"
5352 handle = self.sendline( cmdStr )
5353 assert handle is not None, "Error in sendline"
5354 assert "Command not found:" not in handle, handle
5355 return handle
5356 except AssertionError:
5357 main.log.exception( "" )
5358 return None
5359 except TypeError:
5360 main.log.exception( self.name + ": Object not as expected" )
5361 return None
5362 except pexpect.EOF:
5363 main.log.error( self.name + ": EOF exception found" )
5364 main.log.error( self.name + ": " + self.handle.before )
5365 main.cleanup()
5366 main.exit()
5367 except NotImplementedError:
5368 main.log.exception( self.name + ": Json output not supported")
5369 return None
5370 except Exception:
5371 main.log.exception( self.name + ": Uncaught exception!" )
5372 main.cleanup()
5373 main.exit()
5374
5375 def vplsCreate( self, network ):
5376 """
5377 CLI command to create a new VPLS network.
5378 Required arguments:
5379 network - String name of the network to create.
5380 returns:
5381 main.TRUE on success and main.FALSE on failure
5382 """
5383 try:
5384 network = str( network )
5385 cmdStr = "vpls create "
5386 cmdStr += network
5387 output = self.sendline( cmdStr )
5388 assert output is not None, "Error in sendline"
5389 assert "Command not found:" not in output, output
5390 assert "Error executing command" not in output, output
5391 assert "VPLS already exists:" not in output, output
5392 return main.TRUE
5393 except AssertionError:
5394 main.log.exception( "" )
5395 return main.FALSE
5396 except TypeError:
5397 main.log.exception( self.name + ": Object not as expected" )
5398 return main.FALSE
5399 except pexpect.EOF:
5400 main.log.error( self.name + ": EOF exception found" )
5401 main.log.error( self.name + ": " + self.handle.before )
5402 main.cleanup()
5403 main.exit()
5404 except Exception:
5405 main.log.exception( self.name + ": Uncaught exception!" )
5406 main.cleanup()
5407 main.exit()
5408
5409 def vplsDelete( self, network ):
5410 """
5411 CLI command to delete a VPLS network.
5412 Required arguments:
5413 network - Name of the network to delete.
5414 returns:
5415 main.TRUE on success and main.FALSE on failure
5416 """
5417 try:
5418 network = str( network )
5419 cmdStr = "vpls delete "
5420 cmdStr += network
5421 output = self.sendline( cmdStr )
5422 assert output is not None, "Error in sendline"
5423 assert "Command not found:" not in output, output
5424 assert "Error executing command" not in output, output
5425 assert " not found" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005426 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005427 return main.TRUE
5428 except AssertionError:
5429 main.log.exception( "" )
5430 return main.FALSE
5431 except TypeError:
5432 main.log.exception( self.name + ": Object not as expected" )
5433 return main.FALSE
5434 except pexpect.EOF:
5435 main.log.error( self.name + ": EOF exception found" )
5436 main.log.error( self.name + ": " + self.handle.before )
5437 main.cleanup()
5438 main.exit()
5439 except Exception:
5440 main.log.exception( self.name + ": Uncaught exception!" )
5441 main.cleanup()
5442 main.exit()
5443
5444 def vplsAddIface( self, network, iface ):
5445 """
5446 CLI command to add an interface to a VPLS network.
5447 Required arguments:
5448 network - Name of the network to add the interface to.
5449 iface - The ONOS name for an interface.
5450 returns:
5451 main.TRUE on success and main.FALSE on failure
5452 """
5453 try:
5454 network = str( network )
5455 iface = str( iface )
5456 cmdStr = "vpls add-if "
5457 cmdStr += network + " " + iface
5458 output = self.sendline( cmdStr )
5459 assert output is not None, "Error in sendline"
5460 assert "Command not found:" not in output, output
5461 assert "Error executing command" not in output, output
5462 assert "already associated to network" not in output, output
5463 assert "Interface cannot be added." not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005464 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005465 return main.TRUE
5466 except AssertionError:
5467 main.log.exception( "" )
5468 return main.FALSE
5469 except TypeError:
5470 main.log.exception( self.name + ": Object not as expected" )
5471 return main.FALSE
5472 except pexpect.EOF:
5473 main.log.error( self.name + ": EOF exception found" )
5474 main.log.error( self.name + ": " + self.handle.before )
5475 main.cleanup()
5476 main.exit()
5477 except Exception:
5478 main.log.exception( self.name + ": Uncaught exception!" )
5479 main.cleanup()
5480 main.exit()
5481
5482 def vplsRemIface( self, network, iface ):
5483 """
5484 CLI command to remove an interface from a VPLS network.
5485 Required arguments:
5486 network - Name of the network to remove the interface from.
5487 iface - Name of the interface to remove.
5488 returns:
5489 main.TRUE on success and main.FALSE on failure
5490 """
5491 try:
5492 iface = str( iface )
5493 cmdStr = "vpls rem-if "
5494 cmdStr += network + " " + iface
5495 output = self.sendline( cmdStr )
5496 assert output is not None, "Error in sendline"
5497 assert "Command not found:" not in output, output
5498 assert "Error executing command" not in output, output
5499 assert "is not configured" not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005500 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005501 return main.TRUE
5502 except AssertionError:
5503 main.log.exception( "" )
5504 return main.FALSE
5505 except TypeError:
5506 main.log.exception( self.name + ": Object not as expected" )
5507 return main.FALSE
5508 except pexpect.EOF:
5509 main.log.error( self.name + ": EOF exception found" )
5510 main.log.error( self.name + ": " + self.handle.before )
5511 main.cleanup()
5512 main.exit()
5513 except Exception:
5514 main.log.exception( self.name + ": Uncaught exception!" )
5515 main.cleanup()
5516 main.exit()
5517
5518 def vplsClean( self ):
5519 """
5520 Description: Clears the VPLS app configuration.
5521 Returns: main.TRUE on success and main.FALSE on failure
5522 """
5523 try:
5524 cmdStr = "vpls clean"
5525 handle = self.sendline( cmdStr )
5526 assert handle is not None, "Error in sendline"
5527 assert "Command not found:" not in handle, handle
Jon Hallcf97cf12017-06-06 09:37:51 -07005528 assert "still updating" not in handle, handle
Jon Hall2c8959e2016-12-16 12:17:34 -08005529 return handle
5530 except AssertionError:
5531 main.log.exception( "" )
5532 return main.FALSE
5533 except TypeError:
5534 main.log.exception( self.name + ": Object not as expected" )
5535 return main.FALSE
5536 except pexpect.EOF:
5537 main.log.error( self.name + ": EOF exception found" )
5538 main.log.error( self.name + ": " + self.handle.before )
5539 main.cleanup()
5540 main.exit()
5541 except Exception:
5542 main.log.exception( self.name + ": Uncaught exception!" )
5543 main.cleanup()
5544 main.exit()
5545
5546 def vplsSetEncap( self, network, encapType ):
5547 """
5548 CLI command to add an interface to a VPLS network.
5549 Required arguments:
5550 network - Name of the network to create.
5551 encapType - Type of encapsulation.
5552 returns:
5553 main.TRUE on success and main.FALSE on failure
5554 """
5555 try:
5556 network = str( network )
5557 encapType = str( encapType ).upper()
5558 assert encapType in [ "MPLS", "VLAN", "NONE" ], "Incorrect type"
5559 cmdStr = "vpls set-encap "
5560 cmdStr += network + " " + encapType
5561 output = self.sendline( cmdStr )
5562 assert output is not None, "Error in sendline"
5563 assert "Command not found:" not in output, output
5564 assert "Error executing command" not in output, output
5565 assert "already associated to network" not in output, output
5566 assert "Encapsulation type " not in output, output
Jon Hallcf97cf12017-06-06 09:37:51 -07005567 assert "still updating" not in output, output
Jon Hall2c8959e2016-12-16 12:17:34 -08005568 return main.TRUE
5569 except AssertionError:
5570 main.log.exception( "" )
5571 return main.FALSE
5572 except TypeError:
5573 main.log.exception( self.name + ": Object not as expected" )
5574 return main.FALSE
5575 except pexpect.EOF:
5576 main.log.error( self.name + ": EOF exception found" )
5577 main.log.error( self.name + ": " + self.handle.before )
5578 main.cleanup()
5579 main.exit()
5580 except Exception:
5581 main.log.exception( self.name + ": Uncaught exception!" )
5582 main.cleanup()
5583 main.exit()
5584
5585 def interfaces( self, jsonFormat=True ):
5586 """
5587 Description: Returns result of interfaces command.
5588 Optional:
5589 * jsonFormat: enable json formatting of output
5590 Returns:
5591 The output of the command or None on error.
5592 """
5593 try:
5594 cmdStr = "interfaces"
5595 if jsonFormat:
Jon Halle0f0b342017-04-18 11:43:47 -07005596 raise NotImplementedError
Jon Hall2c8959e2016-12-16 12:17:34 -08005597 cmdStr += " -j"
5598 handle = self.sendline( cmdStr )
5599 assert handle is not None, "Error in sendline"
5600 assert "Command not found:" not in handle, handle
5601 return handle
5602 except AssertionError:
5603 main.log.exception( "" )
5604 return None
5605 except TypeError:
5606 main.log.exception( self.name + ": Object not as expected" )
5607 return None
5608 except pexpect.EOF:
5609 main.log.error( self.name + ": EOF exception found" )
5610 main.log.error( self.name + ": " + self.handle.before )
5611 main.cleanup()
5612 main.exit()
5613 except NotImplementedError:
5614 main.log.exception( self.name + ": Json output not supported")
5615 return None
5616 except Exception:
5617 main.log.exception( self.name + ": Uncaught exception!" )
5618 main.cleanup()
5619 main.exit()
Chiyu Chengec63bde2016-11-17 18:11:36 -08005620
5621 def getTimeStampFromLog( self, mode, searchTerm, splitTerm_before, splitTerm_after, startLine='', logNum=1 ):
5622 '''
5623 Get the timestamp of searchTerm from karaf log.
5624
5625 Arguments:
5626 splitTerm_before and splitTerm_after:
5627
5628 The terms that split the string that contains the timeStamp of
5629 searchTerm. For example, if that string is "xxxxxxxcreationTime =
5630 1419510501xxxxxx", then the splitTerm_before is "CreationTime = "
5631 and the splitTerm_after is "x"
5632
5633 others:
Jon Halle0f0b342017-04-18 11:43:47 -07005634 Please look at the "logsearch" Function in onosclidriver.py
Chiyu Chengec63bde2016-11-17 18:11:36 -08005635 '''
5636 if logNum < 0:
5637 main.log.error("Get wrong log number ")
5638 return main.ERROR
5639 lines = self.logSearch( mode=mode, searchTerm=searchTerm, startLine=startLine, logNum=logNum )
5640 if len(lines) == 0:
5641 main.log.warn( "Captured timestamp string is empty" )
5642 return main.ERROR
5643 lines = lines[ 0 ]
5644 try:
5645 assert type(lines) is str
5646 # get the target value
5647 line = lines.split( splitTerm_before )
5648 key = line[ 1 ].split( splitTerm_after )
5649 return int( key[ 0 ] )
5650 except IndexError:
5651 main.log.warn( "Index Error!" )
5652 return main.ERROR
5653 except AssertionError:
5654 main.log.warn( "Search Term Not Found " )
5655 return main.ERROR
Jon Halle0f0b342017-04-18 11:43:47 -07005656
5657 def workQueueAdd( self, queueName, value ):
5658 """
5659 CLI command to add a string to the specified Work Queue.
5660 This function uses the distributed primitives test app, which
5661 gives some cli access to distributed primitives for testing
5662 purposes only.
5663
5664 Required arguments:
5665 queueName - The name of the queue to add to
5666 value - The value to add to the queue
5667 returns:
5668 main.TRUE on success, main.FALSE on failure and
5669 main.ERROR on error.
5670 """
5671 try:
5672 queueName = str( queueName )
5673 value = str( value )
5674 prefix = "work-queue-test"
5675 operation = "add"
5676 cmdStr = " ".join( [ prefix, queueName, operation, value ] )
5677 output = self.distPrimitivesSend( cmdStr )
5678 if "Invalid operation name" in output:
5679 main.log.warn( output )
5680 return main.ERROR
5681 elif "Done" in output:
5682 return main.TRUE
5683 except TypeError:
5684 main.log.exception( self.name + ": Object not as expected" )
5685 return main.ERROR
5686 except Exception:
5687 main.log.exception( self.name + ": Uncaught exception!" )
5688 main.cleanup()
5689 main.exit()
5690
5691 def workQueueAddMultiple( self, queueName, value1, value2 ):
5692 """
5693 CLI command to add two strings to the specified Work Queue.
5694 This function uses the distributed primitives test app, which
5695 gives some cli access to distributed primitives for testing
5696 purposes only.
5697
5698 Required arguments:
5699 queueName - The name of the queue to add to
5700 value1 - The first value to add to the queue
5701 value2 - The second value to add to the queue
5702 returns:
5703 main.TRUE on success, main.FALSE on failure and
5704 main.ERROR on error.
5705 """
5706 try:
5707 queueName = str( queueName )
5708 value1 = str( value1 )
5709 value2 = str( value2 )
5710 prefix = "work-queue-test"
5711 operation = "addMultiple"
5712 cmdStr = " ".join( [ prefix, queueName, operation, value1, value2 ] )
5713 output = self.distPrimitivesSend( cmdStr )
5714 if "Invalid operation name" in output:
5715 main.log.warn( output )
5716 return main.ERROR
5717 elif "Done" in output:
5718 return main.TRUE
5719 except TypeError:
5720 main.log.exception( self.name + ": Object not as expected" )
5721 return main.ERROR
5722 except Exception:
5723 main.log.exception( self.name + ": Uncaught exception!" )
5724 main.cleanup()
5725 main.exit()
5726
5727 def workQueueTakeAndComplete( self, queueName, number=1 ):
5728 """
5729 CLI command to take a value from the specified Work Queue and compelte it.
5730 This function uses the distributed primitives test app, which
5731 gives some cli access to distributed primitives for testing
5732 purposes only.
5733
5734 Required arguments:
5735 queueName - The name of the queue to add to
5736 number - The number of items to take and complete
5737 returns:
5738 main.TRUE on success, main.FALSE on failure and
5739 main.ERROR on error.
5740 """
5741 try:
5742 queueName = str( queueName )
5743 number = str( int( number ) )
5744 prefix = "work-queue-test"
5745 operation = "takeAndComplete"
5746 cmdStr = " ".join( [ prefix, queueName, operation, number ] )
5747 output = self.distPrimitivesSend( cmdStr )
5748 if "Invalid operation name" in output:
5749 main.log.warn( output )
5750 return main.ERROR
5751 elif "Done" in output:
5752 return main.TRUE
5753 except TypeError:
5754 main.log.exception( self.name + ": Object not as expected" )
5755 return main.ERROR
5756 except Exception:
5757 main.log.exception( self.name + ": Uncaught exception!" )
5758 main.cleanup()
5759 main.exit()
5760
5761 def workQueueDestroy( self, queueName ):
5762 """
5763 CLI command to destroy the specified Work Queue.
5764 This function uses the distributed primitives test app, which
5765 gives some cli access to distributed primitives for testing
5766 purposes only.
5767
5768 Required arguments:
5769 queueName - The name of the queue to add to
5770 returns:
5771 main.TRUE on success, main.FALSE on failure and
5772 main.ERROR on error.
5773 """
5774 try:
5775 queueName = str( queueName )
5776 prefix = "work-queue-test"
5777 operation = "destroy"
5778 cmdStr = " ".join( [ prefix, queueName, operation ] )
5779 output = self.distPrimitivesSend( cmdStr )
5780 if "Invalid operation name" in output:
5781 main.log.warn( output )
5782 return main.ERROR
5783 return main.TRUE
5784 except TypeError:
5785 main.log.exception( self.name + ": Object not as expected" )
5786 return main.ERROR
5787 except Exception:
5788 main.log.exception( self.name + ": Uncaught exception!" )
5789 main.cleanup()
5790 main.exit()
5791
5792 def workQueueTotalPending( self, queueName ):
5793 """
5794 CLI command to get the Total Pending items of the specified Work Queue.
5795 This function uses the distributed primitives test app, which
5796 gives some cli access to distributed primitives for testing
5797 purposes only.
5798
5799 Required arguments:
5800 queueName - The name of the queue to add to
5801 returns:
5802 The number of Pending items in the specified work queue or
5803 None on error
5804 """
5805 try:
5806 queueName = str( queueName )
5807 prefix = "work-queue-test"
5808 operation = "totalPending"
5809 cmdStr = " ".join( [ prefix, queueName, operation ] )
5810 output = self.distPrimitivesSend( cmdStr )
5811 pattern = r'\d+'
5812 if "Invalid operation name" in output:
5813 main.log.warn( output )
5814 return None
5815 else:
5816 match = re.search( pattern, output )
5817 return match.group(0)
5818 except ( AttributeError, TypeError ):
5819 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5820 return None
5821 except Exception:
5822 main.log.exception( self.name + ": Uncaught exception!" )
5823 main.cleanup()
5824 main.exit()
5825
5826 def workQueueTotalCompleted( self, queueName ):
5827 """
5828 CLI command to get the Total Completed items of the specified Work Queue.
5829 This function uses the distributed primitives test app, which
5830 gives some cli access to distributed primitives for testing
5831 purposes only.
5832
5833 Required arguments:
5834 queueName - The name of the queue to add to
5835 returns:
5836 The number of complete items in the specified work queue or
5837 None on error
5838 """
5839 try:
5840 queueName = str( queueName )
5841 prefix = "work-queue-test"
5842 operation = "totalCompleted"
5843 cmdStr = " ".join( [ prefix, queueName, operation ] )
5844 output = self.distPrimitivesSend( cmdStr )
5845 pattern = r'\d+'
5846 if "Invalid operation name" in output:
5847 main.log.warn( output )
5848 return None
5849 else:
5850 match = re.search( pattern, output )
5851 return match.group(0)
5852 except ( AttributeError, TypeError ):
5853 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5854 return None
5855 except Exception:
5856 main.log.exception( self.name + ": Uncaught exception!" )
5857 main.cleanup()
5858 main.exit()
5859
5860 def workQueueTotalInProgress( self, queueName ):
5861 """
5862 CLI command to get the Total In Progress items of the specified Work Queue.
5863 This function uses the distributed primitives test app, which
5864 gives some cli access to distributed primitives for testing
5865 purposes only.
5866
5867 Required arguments:
5868 queueName - The name of the queue to add to
5869 returns:
5870 The number of In Progress items in the specified work queue or
5871 None on error
5872 """
5873 try:
5874 queueName = str( queueName )
5875 prefix = "work-queue-test"
5876 operation = "totalInProgress"
5877 cmdStr = " ".join( [ prefix, queueName, operation ] )
5878 output = self.distPrimitivesSend( cmdStr )
5879 pattern = r'\d+'
5880 if "Invalid operation name" in output:
5881 main.log.warn( output )
5882 return None
5883 else:
5884 match = re.search( pattern, output )
5885 return match.group(0)
5886 except ( AttributeError, TypeError ):
5887 main.log.exception( self.name + ": Object not as expected; " + str( output ) )
5888 return None
5889 except Exception:
5890 main.log.exception( self.name + ": Uncaught exception!" )
5891 main.cleanup()
5892 main.exit()